JDK-8347057 : Local class cannot be instantiated from a static context
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 24
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2025-01-06
  • Updated: 2025-01-06
  • Resolved: 2025-01-06
Related Reports
Relates :  
Description
Consider:

{code:java}
public interface A {
  static A localSingleton() {
    class B implements A {
      private static final A INSTANCE = new B(); 
    }
    return B.INSTANCE;
  }
}
{code}

The idea is to avoid exposing publicly class B (as classes declared in interfaces are `public` by default).

The class above compiles with Java 23 and less, but fails with Java 24-ea+30 with:

{noformat}
A.java:4: error: local class B cannot be instantiated from a static context
      private static final A INSTANCE = new B(); 
                                        ^
1 error
{noformat}
Comments
Thanks for the explanation! The issue can be closed.
06-01-2025

This change in behavior reflects the new specification changes here: https://cr.openjdk.org/~gbierman/jep492/jep492-20241205/specs/flexible-constructor-bodies-jls.html See: ``` If C is an inner local class, then: If C occurs in a static context, then i has no immediately enclosing instance. Let S be the nearest static method declaration, static field declaration, or static initializer that encloses the declaration of C. If the nearest static method declaration, static field declaration, or static initializer that encloses the class instance creation expression is not S, then a compile-time error occurs. [ This missing condition is a bugfix for extensions introduced in JEP 395. ] ``` Basically, the spec now makes sure that it is not possible to create a local inner class from a _different_ static context from the one in which it has been declared. Because if we allowed that, this would lead to issues when the local classes captures e.g. parameters from the enclosing static method (as such parameters are not available in the context where the local class is instantiated). We have considered making the spec text more precise, by distinguishing between capturing and non-capturing local classes, but concluded that specifying the exact behavior of captured variables in the JLS was too much. The correct fix for this kind of issues would be to allow a `static` modifier in the local class declaration, to make it clear that this local class can't capture. Then the above idiom would work w/o issues.
06-01-2025