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