JDK-8254321 : Allow static members to be declared in inner classes
  • Type: CSR
  • Component: tools
  • Sub-Component: javac
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 16
  • Submitted: 2020-10-09
  • Updated: 2024-06-25
  • Resolved: 2020-11-19
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Summary
-------

Relax language restrictions that prohibit `static` members declared by inner classes.


Problem
-------

Since nested classes were first introduced to Java, nested class declarations that are _inner_ have been prohibited from declaring `static` members, with the exception of static final fields initialized by constant expressions. This restriction applies to non-`static` member classes, local classes, and anonymous classes. It simplifies the language's task of resolving and validating references to in-scope variables, methods, etc.

In JEP 384, the second preview of Record Classes added support for _local_ interfaces, enum classes, and record classes. This was a well-received enhancement, permitting coding styles that reduce the scope of certain declarations to local contexts. It required enhancing the language so that references to variables, types, methods, and `this` are appropriately restricted when appearing anywhere within a nested `static` construct.

While JEP 384 allowed for static _local_ classes and interfaces, it did not relax the restriction on static _member_ classes and interfaces of inner classes. So an inner class can declare a static interface inside one of its method bodies, but not as a class member.

As a natural next step, JEP 395 proposes further relaxing nesting restrictions, permitting static classes, methods, fields, etc., to be declared within inner classes. The language changes in JEP 384 already address the problems of how variable and method references, etc., behave in these contexts, so all that needs changing is a removal of the restriction.


Solution
--------

Remove restrictions that disallow static declarations in inner classes, which include non-`static` member classes, local classes, and anonymous classes. Newly-allowed declarations include:

* `static` fields
* `static` methods
* `static` member classes and interfaces
* `static` initializers

Nested static declarations have no access to enclosing instances, local variables, or type parameters. These rules have already been established by JEP 384 to handle local interfaces, enums, and records.

Because inner classes can inherit static members, this has no impact on the language's treatment of qualified member accesses occurring elsewhere.

This change has no impact on existing programs—it expands the set of legal programs, but does not make any existing programs illegal or change their behavior.


Specification
-------------

The proposed change to the specification are discussed in detail in the document on Local and Nested Static Declarations. See also JDK-8253374.
Comments
[~darcy] thanks for the approval
20-11-2020

Moving to Approved.
19-11-2020

[~darcy] got it sorry, I have finalized it
17-11-2020

Hi [~vromero], per the CSR process (https://wiki.openjdk.java.net/display/csr/Main), the assignee generally has the responsibility of indicating when the proposal should be Finalized for the last phase of review.
10-11-2020

Hi [~darcy], you moved this CSR to Provisional, are you waiting from any additional input from us? Thanks
10-11-2020

Moving to Provisional.
10-11-2020

[~darcy] hi Joe, are you OK with Dan's answer? Thanks
27-10-2020

The rule about nested annotation declarations was added when we introduced local interfaces/enums/records, because these classes _already_ allow static members. See the preview feature specification in 15: https://docs.oracle.com/en/java/javase/15/docs/specs/local-statics-jls.html#jls-9.6. As you observe, the restriction is implicit in pre-15 code, where it is impossible for an annotation declaration to appear anywhere other than top-level or nested within a chain of static classes/interfaces.
19-10-2020

Moving to Provisional. Please expand the colloquial description of the solution to include more information. Is the explicit new rules for annotation types "It is a compile-time error if an annotation declaration is nested within the body of a local class or interface declaration (14.3), or within the body of an anonymous class (15.9.5)." and existing restriction that now needs an explicit statement due to loosening of rules for interfaces?
14-10-2020