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?

questionAnswers(4)

yourAnswerToTheQuestion