I am currently trying to understand how Java infers the type of lambda expressions. I can illustrate with an example:
Writing:
producer.send(record, new Callback() {
public void onCompletion(RecordMetadata metadata, Exception exception) {
if (exception == null) {
logger.info("Received new metadata"
);
} else {
logger.error("Error while producing " + exception);
My IDE suggested that can be re-written to:
producer.send(record, (metadata, exception) -> {
if (exception == null) {
logger.info("Received new metadata"
);
} else {
logger.error("Error while producing " + exception);
}
Which made me think: How does the compiler guess the types for metadata and exception?
Reading through some articles like this, I found that:
Java 8 also introduced Lambda Expressions. Lambda Expressions do not have an explicit type. Their type is inferred by looking at the target type of the context or situation. The Target-Type of an expression is the data type that the Java Compiler expects depending on where the expression appears.
I am not sure what is meant here by "context or situation". I am looking for a better technical explanation of how the compiler infers types. And when would I need to explicitly tag types.
Runnable foo =inRunnable foo = () -> System.out.println("hello");. Or, in your case, what the methodsendexpects. In any case, a lambda is always subject to some interface. You can only use a lambda in a context where an interface is expected. The lambda will then basically create some kind of anonymous instance of this interface. Hence the types are determined by the expected interface. (the interface must be functional, so only contain one to-be-implemented method)