Accessibility of classes nested in local classes

Dan Smith daniel.smith at oracle.com
Mon Jan 4 21:12:00 UTC 2021


> On Jan 4, 2021, at 12:35 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
> 
> To clarify, you are not proposing any spec changes, just bringing `javac` in line with with the spec says?

That's my preference here, yes. Unless there's some reason to keep javac's longstanding behavior.

> 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.  

At the language level, access restrictions on a local class are nonsensical, because their purpose is to limit who can access or inherit *members* of something else. (For example, which names can be used after a dot.)

At the JVM level, access restrictions are used to determine who can mention a class at all. It's a different concept. The compiler is responsible for choosing a JVM access that is good enough to support language-level access requirements (constrained, as a best practice, by the principle of least privilege), and then reflection exposes those compiler choices.

So a 'public' modifier on a local class would be something entirely new—an instruction to the compiler about what sort of JVM-level access the author requires, beyond the language's requirements. That's a new feature we could explore, of course; because it's something new, maybe 'public' isn't even the keyword we want to use. But the narrow use case makes me wonder if it's better handled as an API problem—e.g., with an appropriate Lookup object, the SQL library can do whatever reflective operations it wants.



More information about the amber-spec-experts mailing list