title: Why does a lambda need to capture the enclosing instance when referencing a final String field?
body: <p>This is based on <a href="https://stackoverflow.com/questions/36187451/java-lambda-referencing-enclosing-object-replace-with-private-static-class">this question</a>. Consider this example where a method returns a <code>Consumer</code> based on a lambda expression:</p>
  
  <pre><code>public class TestClass {
      public static void main(String[] args) {
          MyClass m = new MyClass();
          Consumer&lt;String&gt; fn = m.getConsumer();
  
          System.out.println("Just to put a breakpoint");
      }
  }
  
  class MyClass {
      final String foo = "foo";
  
      public Consumer&lt;String&gt; getConsumer() {
          return bar -&gt; System.out.println(bar + foo);
      }
  }
  </code></pre>
  
  <p>As we know, it's not a good practice to reference a current state inside a lambda when doing functional programming, one reason is that the lambda would capture the enclosing instance, which will not be garbage collected until the lambda itself is out of scope.</p>
  
  <p>However, in this specific scenario related to <code>final</code> strings, it seems the compiler could have just enclosed the constant (<code>final</code>) string <code>foo</code> (from the constant pool) in the returned lambda, instead of enclosing the whole <code>MyClass</code> instance as shown below while debugging (placing the breaking at the <code>System.out.println</code>). Does it have to do with the way lambdas are compiled to a special <code>invokedynamic</code> bytecode?</p>
  
  <p><a href="https://i.stack.imgur.com/AwrSA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/AwrSA.png" alt="enter image description here"></a></p>