Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8328649 Disallow enclosing instances for local classes in constructor prologues
  3. JDK-8329669

Release Note: Local Classes Declared before Superclass Construction No Longer Have Enclosing Instances

XMLWordPrintable

    • generic
    • generic

      Local classes declared inside superclass constructor invocation parameter expressions are no longer compiled with immediately enclosing outer instances.

      According to JLS 21 §15.9.2, local and anonymous classes declared in a static context do not have immediately enclosing outer instances. This includes classes declared inside a parameter expression of a `super()` or `this()` invocation in a constructor for some class `C`. Previously, the compiler was incorrectly allowing local classes declared within such parameter expressions to contain references to the `C` outer instance; this is no longer allowed. Although previously allowed, such references were pointless because any subsequent attempt to instantiate the class would trigger a `cannot reference this before supertype constructor has been called` error. Note that the compiler was already correctly disallowing anonymous classes from containing such references.

      Although declaring an anonymous inner class within a `super()` or `this()` parameter expression is easy and common, for example in an expression like `super(new Runnable() { ... })`, declaring a local class within a `super()` or `this()` parameter expression is much less common as it requires more syntactic gymnastics. Here's an example that compiled previously but no longer compiles after this change:
      ```
      import java.util.concurrent.atomic.*;
      public class Example extends AtomicReference<Object> {
          public Example() {
              super(switch (0) {
                  default -> {
                      class Local {
                          { System.out.println(Example.this); }
                      }
                      yield null;
                      // yield new Local(); // generates compiler error
                  }
              });
          }
      }
      ```
      After this change, the reference to `Example.this` generates a `no enclosing instance of type Example is in scope` compiler error.

            acobbs Archie Cobbs
            acobbs Archie Cobbs
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: