Followup of discussion in last week's meeting: how does 'new Object()' interact
with the IdentityObject interface?
I've been able to get the story down to a few concrete changes that feel
manageable.
---
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.
- 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.
- (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'.)
- (Optionally) Make Object 'abstract'.
---
Language changes
- The expressions 'new Object()' and 'Object::new' trigger a warning. ("Use
'Object.newIdentity' or 'new SimpleIdentityObject' instead.")
- If Object has been made abstract, 'new Object()' and 'Object::new' are exempt
from the abstract class error check.
- (Optionally) In a future iteration of the language, 'new Object()' and
'Object::new' are errors (perhaps by removing the abstract class exemption).
---
JVM changes
- At runtime, the instruction 'new java/lang/Object' behaves as if it were 'new
java/lang/SimpleIdentityObject'. Note that, for this reason,
SimpleIdentityObject needs a well-defined, specified name. (Although we don't
necessarily have to perform access control...)
- If Object has been made abstract, the instruction 'new java/lang/Object' does
not perform the link-time check for an abstract class.
(The 'invokespecial Object.<init>()V' instruction is unchanged. It continues to
invoke the Object constructor. Verification allows it, even though the object
on the stack may be an uninitialized SimpleIdentityObject, because the 'new'
instruction names 'java/lang/Object'. This may violate some assumptions about
initialization method execution, but is sound because SimpleIdentityObject
doesn't need to do any initialization.)
I'm not sure we'll ever be able to deprecate 'new java/lang/Object' in the JVM,
but I suppose it's possible, with some disruption, for version X.0+ classes.
JVMs will still need to support older class files.
---
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.)