Accessibility of classes nested in local classes

Brian Goetz brian.goetz at oracle.com
Mon Jan 4 19:35:26 UTC 2021


To clarify, you are not proposing any spec changes, just bringing 
`javac` in line with with the spec says?

This raises another issue: visibility of the local classes themselves.  
You can't say `public` in front of `class Local`. On the one hand, your 
"in practice" explanation covers the motivation -- you can't access it 
outside of the enclosing method.  But, that's not entirely true.  What 
about:

```
void m() {
     record R(int x, int y) { }

     FancyResultSet queryResult = doSomeSqlQuery();
     Stream<R> rs = queryResult.asStream(R.class);
     for (R r : rs) { ... }
}
```

It's entirely reasonable to ask a SQL (or JSON, or whatever) library to 
return its results as a sequence of some record, binding data to 
components based on query metadata + record reflection.  But, if you try 
the above, you'll get some sort of accessibility error as the library 
tries to reflect over the R.class handed to it _by the "owner" of R_.

One way to address this would be to allow `public` on the local class 
declaration.

On 1/4/2021 2:10 PM, Dan Smith wrote:
> javac has longstanding behavior, apparently unspecified, to reject accessibility modifiers on classes nested within an anonymous or local class. The changes involved in supporting statics inside of local classes have drawn attention to this behavior.
>
>      void m() {
>          class Local {
>
>              private class C1 {} // error
>              class C2 {}
>              protected class C3 {} // error
>              public class C4 {} // error
>
>              class Inner {
>                  private class D1 {} // error
>                  class D2 {}
>                  protected class D3 {} // error
>                  public class D4 {} // error
>              }
>          }
>      }
>
> There's nothing in 8.1.1, 14.3, 15.9.5, or 8.5 to suggest this behavior. (There's a rule about modifiers on a local class declaration itself, but nothing about its members.)
>
> In practice, members of local classes are essentially private anyway—there is no way to refer to them outside of the local class's enclosing method. So the access modifiers don't seem that useful. But they do affect things like inheritance (local class B extends local class A) and reflection. And while this same argument applies to fields, javac allows unrestricted use of field access modifiers inside local classes.
>
> I think the appropriate resolution is to treat this as a javac bug and remove the access modifier restriction. Any reasons not to do so?
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20210104/748aba8b/attachment-0001.htm>


More information about the amber-spec-experts mailing list