Re-interpreting 'new Object()'
Brian Goetz
brian.goetz at oracle.com
Thu Sep 3 14:12:43 UTC 2020
This sounds mostly in line with what I was expecting. Some minor
comments inline.
> API changes
>
> - Add a java.lang.IdentityObject interface. The interface has no members (don't want to disrupt method resolution, etc., in any way). The javadoc, for information purposes, describes the behaviors of various Object methods.
It's a shame this isn't the home for identityHashCode, but oh well.
> - Add a public java.lang.SimpleIdentityObject class (I'm happy to entertain alternative names). The class has a default constructor, no members, and is 'final'. It will implicitly implement IdentityObject. The javadoc describes how it can be used as a general-purpose lock or sentinel.
An almost-attractive bikeshed color here is a nested (static final)
class -- Object.Identity. This means you say
new Object.Identity()
when you want ... a new object identity and nothing else.
Except ... this class is inherited ... grr. I have always wished
static nested classes were not inherited.
In the absence of that, calling it ObjectIdentity would suffice:
Object lock = new ObjectIdnetity()
> - (Optionally) Add a static 'newIdentity()' method to Object, implemented as 'return new SimpleIdentityObject()'. Return type TBD. (Caution: we've never added a method to Object before. If anyone else has used that name anywhere, it will conflict. May also cause surprising reflection results from, e.g., 'getMethods'.)
If we had a nested class, the method would not really be needed, since
the primary purpose of the method would be discoverability.
> - (Optionally) Make Object 'abstract'.
I think there's a pile of things we can do later to finish the job, and
this could be in it.
> - (Optionally) In a future iteration of the language, 'new Object()' and 'Object::new' are errors (perhaps by removing the abstract class exemption).
Also in the pile of "for later".
> ---
>
> Bonus discussion: Here's an alternative story, if we wanted to pursue a particular kind of factory methods in the language:
>
> - Classes, including abstract classes and interfaces, can declare a static method named 'new', returning the class's type. (Syntax subject to bikeshedding.)
>
> - 'new ClassName' can be used to invoke these methods as if they were constructors, without the usual hostility to abstract classes and interfaces. Invocations compile to 'invokestatic'.
>
> - The Object class is updated to be abstract but provide one of these factories. There is no 'newIdentity' method.
>
> - The above language changes don't apply.
>
> - The above JVM changes are still needed. (We still have legacy 'new java/lang/Object' code.)
>
This idea has come up in almost this exact form before (several times)
in different contexts. FWIW, each time, it seems initially attractive,
and then after some thought, doesn't seem to deliver the punch one might
hope. (You could think of this as an limited form of operator
overloading.)
A big drawback has always been that it throws a treasured invariant
under the bus: `new Foo()` always returns a unique, unaliased, non-null
reference. Lots of existing code subtly depends on this, as do many
optimizations and security analyses. (Though, inline classes already
do some of that damage, at least in part.)
But my sense is that this is yet another place where it is a bigger
hammer, with more costs, than is needed to solve this problem. And I'm
not sure users are better served by muddying what `new` means for the
sake of not changing the relatively infrequent "I need a new idnetity"
invocations.
More information about the valhalla-spec-experts
mailing list