Class modifiers in Java 16

Tagir Valeev amaembo at gmail.com
Thu May 27 10:22:48 UTC 2021


Hello!

I want to clarify my understanding of Java 16 spec and the
corresponding compiler behavior regarding class modifiers (8.1.1)

1. static modifier
Java 15 spec 8.1.1 [1] says:
The modifier static pertains only to member classes (§8.5.1), not to
top level or local or anonymous classes.

Java 16 spec 8.1.1 [2] says:
The modifier static pertains only to member classes and local classes.
However, Java 16 spec 14.3 says:
It is a compile-time error if a local class or interface declaration
has the modifier static (§8.1.1).

Is it my bad understanding of English or there's some contradiction?
To me, 8.1.1 says that now, local classes can be declared as static
while 14.3 says the opposite thing.

2. public/private/protected on members of local/anonymous classes
Consider the following class:
class Test {
  void test() {
    class Local {
      public class X{}
      protected class Y{}
      private class Z{}
    }
    new Object() {
      public class X{}
      protected class Y{}
      private class Z{}
    };
  }
}
It's compilable without errors with javac 16, as well as javac
17-ea+6-358. However, javac 15 displays the following errors:

>"C:\Program Files\Java\jdk-15\bin\javac.exe" Test.java
Test.java:4: error: modifier public not allowed here
      public class X{}
             ^
Test.java:5: error: modifier protected not allowed here
      protected class Y{}
                ^
Test.java:6: error: modifier private not allowed here
      private class Z{}
              ^
Test.java:9: error: modifier public not allowed here
      public class X{}
             ^
Test.java:10: error: modifier protected not allowed here
      protected class Y{}
                ^
Test.java:11: error: modifier private not allowed here
      private class Z{}
              ^
6 errors

Is it the expected behavior change, a regression, or a fix of a
previously existing bug? I see the following change in spec [1], [2],
regarding private and protected:
Java 15: The access modifiers protected and private pertain only to
member classes within a directly enclosing class declaration
Java 16: The access modifiers protected and private pertain only to
member classes.

I'm not sure I understand how deletion of "within a directly enclosing
class declaration" changes the meaning. I think that member classes
are always within a directly enclosing class declaration. I also see
no spec changes about "public" modifier behavior. To me, it looks like
the behavior in Java 15 and older was incorrect and it was fixed in
Java 16. But probably I'm missing something?

Thank you in advance,
With best regards,
Tagir Valeev.

[1] https://docs.oracle.com/javase/specs/jls/se15/html/jls-8.html#jls-ClassModifier
[2] https://docs.oracle.com/javase/specs/jls/se16/html/jls-8.html#jls-ClassModifier
[3] https://docs.oracle.com/javase/specs/jls/se16/html/jls-14.html#jls-14.3


More information about the amber-dev mailing list