I'm a little bit confused about Java lambdas and method references behaviour. For ex., we have this code:
import java.util.function.Consumer;
public class Main {
private static StringBuilder sBuilder = new StringBuilder("1");
public static void main(String[] args) {
Consumer<String> consumer = s -> sBuilder.append(s);
sBuilder = new StringBuilder("2");
consumer.accept("3");
System.out.println(sBuilder);
}
}
Output:
23
This works as expected, but if we replace
s -> sBuilder.append(s)
with
sBuilder::append
the output will be:
2
Have you any ideas how to explain this? This isn't the same things? Thanks.
In the lambda expression, the
sBuilder
field is captured, but not evaluated. It will only be evaluated when the corresponding function interface method is invoked. At that point, thesBuilder
references the new instance created and assigned to the field withIn the method reference, the
sBuilder
field is evaluated immediately to produce aConsumer
instance. That value references the instance created in the static initializerand the
Consumer
will operate on that one. You print the new one.From the Java Language Specification, concerning the Run-Time Evaluation of Method References