Unnamed classes (was: Paving the on-ramp)

Brian Goetz brian.goetz at oracle.com
Wed Oct 19 20:35:46 UTC 2022

Let's pull on this string.

When we say `javac Foo.java`, the compiler has to create a class file, 
and doesn't have the benefit of a declared class name. The logical 
output file is `Foo.class`, because otherwise the next thing the user is 
likely to do is `java Foo`, and the class loader is going to look for 

A .class file has a ClassFile structure, which has a `this_class` field 
which names the current class.  We experimented with calling the class 
something like `$Foo` or $Unnamed, but this trick just garners a 
NoClassDefFoundError, with reason "wrong name".  This error comes from 
the native method `ClassLoader::defineClass1`.

With inner classes, we've taken the position that class names with $ in 
their name are likely to be unstable names not to be counted on.  So 
calling it $Foo sends that signal, good.  But we'd have to be willing to 
loosen the checking in the class loader to allow loading a class with a 
slightly mangled name such as $Unnamed (and then make the launcher more 
tolerant of that.)

On 10/19/2022 4:16 PM, John Rose wrote:
> On 19 Oct 2022, at 9:43, Brian Goetz wrote:
>     The alternative is to view these as _implicitly named_ classes,
>     where they have a name, just derived from the file system rather
>     than the source code.
> I’d like to discourage this idea. We already have nameless classes 
> with non-denotable names, and programmers know how to use them. We 
> don’t really have implicitly-named classes. (Except maybe in a weak 
> sense for certain well-defined bytecode names like |pkg/Foo$Bar|, for 
> member classes which already have an explicit name |Foo.Bar|; arguably 
> |Foo$Bar| is an implicit name. But it cannot appear in source.)
> If we introduce a new way of naming (implicit names) we will have to 
> roll out rules for mapping the name-precursor (a filename) to a name. 
> This will have its own headaches, since different OSs have different 
> alphabets and syntaxes, and none of those alphabets or syntaxes are 
> fully compatible with native Java class names. So we’d have to saddle 
> ourselves with a name mangling scheme to launder a random filename 
> into a source-denotable Java class name. If ever there was a siren 
> song, this is a loud one!
> Maybe the first place you’d want a name is a constructor declaration, 
> not as an API point but as a place to put random setup code. Instance 
> initialization blocks (though nobody loves them) supply a workaround 
> for placing such random setup code. I suppose we could put some 
> lipstick on them by allowing (eventually requiring) them to start with 
> a keyword like |class| or |this|, in parallel to |static| for static 
> initialization blocks. Or (different lipstick shade) allowing the 
> init-blocks to somehow attach to field declarations, since that’s how 
> they are used in many cases (both static and non-static).
> Since the next-best workaround is to give the class a name, or use a 
> nested class to carry all the logic, and since that next-best 
> workaround is not too expensive, I think the payoff for adding such 
> lipstick is really small, but it’s something I’ve thought of before 
> and might be worth keeping in the back pocket.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20221019/3630add0/attachment-0001.htm>

More information about the amber-spec-experts mailing list