IdentityObject & abstract superclasses

Dan Smith daniel.smith at oracle.com
Wed Sep 2 23:30:17 UTC 2020


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.



More information about the valhalla-spec-experts mailing list