I don't understand a couple of things with lambda.
String s = "Hello World";
Function<Integer, String> f = s::substring;
s = null;
System.out.println(f.apply(5));
Why is the f.apply
method still working if s = null
. After all, the String
object should be deleted by the GC because there is no pointer that points to the object.
One more thing, why don't I need a return statement here?
Function<Integer, String> f = t -> t + "";
When specifying only a single lambda statement, its value is automatically returned from the lambda.
Java works with pass-by-value. So,
f
is a reference copy.Let's convert that method reference to a lambda and see what happens:
The above doesn't compile because
s
is being changed outside of the lambda, so it is not effectively final. Therefore, we can deduce that using a method reference caches the value ofs
before it's actually used.See: Is method reference caching a good idea in Java 8?
The JLS, Section 15.13.3 describes the runtime evaluation of method references.
(bold emphasis mine)
Basically the reference to
s
as it is for the method reference is stored for later execution. Here, the string"Hello World"
is saved for later execution of the method reference. Because of this, even if you sets
tonull
after the declaration of the method reference, but before you execute theFunction
, it will still use the string"Hello World"
.Setting something to
null
does not guarantee that the garbage collector will collect it, and it won't guarantee that it's collected immediately.Also, here, there still is a reference in the method reference, so it won't get garbage collected at all here.
Finally, lambda expression bodies have 2 forms: an expression and a block of statements with (possibly) a return statement. With
That is an expression. The block statement equivalent would be: