The JLS, Section 15.13.3 describes the runtime evaluation of method references.
The timing of method reference expression evaluation is more complex than that of lambda expressions (§15.27.4). When a method reference expression has an expression (rather than a type) preceding the :: separator, that subexpression is evaluated immediately. The result of evaluation is stored until the method of the corresponding functional interface type is invoked; at that point, the result is used as the target reference for the invocation. This means the expression preceding the :: separator is evaluated only when the program encounters the method reference expression, and is not re-evaluated on subsequent invocations on the functional interface type.
(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 set s
to null
after the declaration of the method reference, but before you execute the Function
, 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
Function<Integer, String> f = t -> t + "";
That is an expression. The block statement equivalent would be:
Function<Integer, String> f = t -> { return t + "";};
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…