Warum muss ein Lambda die einschließende Instanz erfassen, wenn auf ein endgültiges String-Feld verwiesen wird?

Dies basiert aufdiese Frag. Betrachten Sie dieses Beispiel, in dem eine Methode ein @ zurückgibConsumer basierend auf einem Lambda-Ausdruck:

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);
    }
}

Wie wir wissen, ist es keine gute Praxis, bei der funktionalen Programmierung auf einen aktuellen Zustand innerhalb eines Lambda zu verweisen. Ein Grund dafür ist, dass das Lambda die umschließende Instanz erfasst, die erst dann müllsammelt, wenn das Lambda selbst außerhalb des Gültigkeitsbereichs liegt.

In diesem speziellen Szenario jedoch im Zusammenhang mitfinal Strings, es scheint, als hätte der Compiler die Konstante einfach eingeschlossen final) stringfoo (aus dem konstanten Pool) im zurückgegebenen Lambda, anstatt das ganze @ einzuschließMyClass -Instanz wie unten gezeigt beim Debuggen (Platzieren der Unterbrechung amSystem.out.println). Hat es mit der Art und Weise zu tun, wie Lambdas zu einem speziellen @ kompiliert werdeinvokedynamic Bytecode?

Antworten auf die Frage(8)

Ihre Antwort auf die Frage