Por que um lambda precisa capturar a instância envolvente ao fazer referência a um campo String final?
Isto é baseado emessa questão. Considere este exemplo em que um método retorna umConsumer
com base em uma expressão lambda:
public class TestClass {
public static void main(String[] args) {
MyClass m = new MyClass();
Consumer<String> fn = m.getConsumer();
System.out.println("Just to put a breakpoint");
}
}
class MyClass {
final String foo = "foo";
public Consumer<String> getConsumer() {
return bar -> System.out.println(bar + foo);
}
}
Como sabemos, não é uma boa prática fazer referência a um estado atual dentro de um lambda ao executar programação funcional, uma razão é que o lambda capturaria a instância anexa, que não será coletada como lixo até que o próprio lambda esteja fora de escopo.
Entretanto, nesse cenário específico relacionado afinal
seqüências de caracteres, parece que o compilador poderia apenas incluir a constante (final
) cordafoo
(do pool constante) no lambda retornado, em vez de incluir todo oMyClass
instância, como mostrado abaixo durante a depuração (colocando a quebra noSystem.out.println
) Isso tem a ver com a maneira como as lambdas são compiladas para uminvokedynamic
bytecode?