Summarizing, here's what I think we want: --- Language features
java.lang.IdentityObject is a normal interface, can be implemented/extended by any class or interface. A non-inline class with any of the following properties implicitly implements IdentityObject: - Is concrete (java.lang.Object excluded) - Declares a (possibly private) instance field - Is an inner class with an enclosing instance - Declares an instance initializer - Lacks a no-arg constructor (explicit or implicit) - Declares a no-arg constructor with a non-empty body (something other than 'super();') - Declares a synchronized method A warning encourages classes in the last four categories to explicitly implement IdentityObject in order to ensure stable class evolution. (Possibly of the "this will become an error in a future release" variety.) (Note that I'm tentatively allowing constructor overloading in a non-IdentityObject class. It's not generally useful, but is harmless and could be useful in some special circumstances.) It is a compile-time error if (among other things) an inline class: - Implements IdentityObject, directly or indirectly - Can't access its superclass's no-arg constructor - Declares a synchronized method --- JVM features Traditionally, a class declares that it supports identity subclasses by declaring one or more <init> methods. (Because with no <init> method, it's impossible to initialize a subclass instance.) Similarly, a class declares that it supports inline subclasses by declaring an <init> method whose ACC_ABSTRACT flag is set. Invocations of that method are no-ops. (Tentatively. We could encode this differently. The important metadata is i) the class supports inline subclasses, and ii) access flags for inline subclasses.) A class that is not inline and does not declare support for inline subclasses implicitly implements IdentityObject. A class that declares support for inline subclasses is subject to the following constraints at class load time: - Must be ACC_ABSTRACT (java.lang.Object excluded) - Must not declare an instance field - Must not declare a synchronized method - Must not implement IdentityObject, directly or indirectly - Must have access to extend the superclass (per the super's abstract <init> method) An inline class is subject to similar constraints at class load time: - Must not be ACC_ABSTRACT and must be ACC_FINAL - All fields must be ACC_FINAL - Must not declare a synchronized method - Must not implement IdentityObject, directly or indirectly - Must have access to extend the superclass (per the super's abstract <init> method) --- API features (Optionally) The method Class.Interfaces(), and similar reflection API points, filters out IdentityObject when it is not explicitly named in the class file.