Ответ 1
JLS, раздел 15.13.3 описывает оценку времени выполнения ссылок на методы.
Сроки оценки ссылочного выражения метода более сложны, чем вычисления лямбда-выражений (§15.27.4). Когда ссылочное выражение метода имеет выражение (а не тип), предшествующее разделителю ::, это подвыражение оценивается немедленно. Результат оценки сохраняется до тех пор, пока не будет вызван метод соответствующего типа функционального интерфейса; в этот момент результат используется как целевая ссылка для вызова. Это означает, что выражение, предшествующее разделителю ::, оценивается только тогда, когда программа встречает ссылочное выражение метода и не переоценивается при последующих вызовах типа функционального интерфейса.
(смелый акцент мой)
В основном ссылка на s
как и на ссылку метода, сохраняется для последующего выполнения. Здесь строка "Hello World"
сохраняется для последующего выполнения ссылки на метод. Из-за этого, даже если вы задали значение s
null
после объявления ссылки на метод, но перед выполнением Function
все равно будет использоваться строка "Hello World"
.
Установка null
не гарантирует, что сборщик мусора соберет его, и он не гарантирует, что он будет собран немедленно.
Кроме того, здесь все еще есть ссылка в ссылке на метод, поэтому он вообще не будет собирать мусор.
Наконец, тела выражения лямбда имеют 2 формы: выражение и блок операторов с (возможно) оператором return. С
Function<Integer, String> f = t -> t + "";
Это выражение. Эквивалент блока:
Function<Integer, String> f = t -> { return t + "";};