The plan of record for compiling the constructors of inline classes is to
generate static methods named "<init>" with an appropriate return type, and
invoke them with 'invokestatic'.
This requires relaxing the existing restrictions on method names and
references. Historically, the special names "<init>" and "<clinit>" have been
reserved for special-purpose JVM rules (for example, 'invokespecial' is treated
like a distinct instruction if it invokes a method named '<init>'); for
convenience, we've also prohibited all other method names that include the
characters '<' or '>' (JVMS 4.2.2).
Equivalently, we might say that, within the space of method names, we've carved
out a reserved space for special purposes: any names that include '<' or '>'.
A few months ago, I put together a tentative specification that effectively
cedes a chunk of the reserved space for general usage [1]. The names "<init>"
and "<clinit>" are no longer reserved, *unless* they're paired with descriptors
of a certain form ("(.*)V" and "()V", respectively). Pulling on the thread, we
could even wonder whether the JVM should have a reserved space at all—why can't
I name my method "bob>" or "<janet>", for example?
In retrospect, I'm not sure this direction is such a good idea. There is value
in having well-known names that instantly indicate important properties,
without having more complex tests. (Complex tests are likely to be a source of
bugs and security exploits.) Since the JVM ecosystem is already accustomed to
the existence of a reserved space for special method names, we can keep that
space for free, while it's potentially costly to give it up.
So here's a alternative design:
- "<init>" continues to indicate instance initialization methods; "<clinit>"
continues to indicate class initialization methods
- A new reserved name, "<new>", say, can be used to declare factories
- To avoid misleading declarations, methods named "<new>" must be static and
have a return type that matches their declaring class; only 'invokestatic'
instructions can reference them
- The rest of the "<.*>" space of names (plus ".*<.*" and ".*>.*") is held in
reserve, available for special purposes as we discover them
The Java compiler would only use "<new>" methods for inline class construction,
for now; perhaps in the future we'll find other use cases that make sense (like
surfacing some sort of factory mechanism).
Does this seem promising? Any particular reason it's better to overload
"<init>" than just come up with a new special name?
[1]
http://cr.openjdk.java.net/~dlsmith/lw2/lw2-20190628/specs/init-methods-jvms.html