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