IdentityObject and InlineObject

Brian Goetz brian.goetz at
Wed Apr 8 16:54:03 UTC 2020

This is a good time to review the motivations for Identity/InlineObject, 
and see if there's anything we want to tweak about it.

There are two main branches of the motivation here: pedagogical and 

Pedagogically, we're asking users to amend their view of "object" to 
allow for some objects to have identity, and some objects to not have 
identity, and supertypes are one of the prime ways we capture these 
sorts of divisions.  It's not an accident that we have both the informal 
statement "everything (except primitives) is an object" and the 
hierarchy constraint "all classes extend (implicitly or not) 
java.lang.Object".  Not only is Object a place to hang the behavior that 
is common to all objects (equality, etc), its position at the root of 
the hierarchy sends a message that conditions how we think about 
objects.  The intent of partitioning Object into IdentityObject and 
InlineObject is an attempt to capture the same.

Functionally, there are operations that apply only to identity objects, 
such as identity equality, synchronization, Object::wait, etc.  Some of 
these have been totalized appropriately (such as `==`); others are 
partial.  Having synchronization be partial, without offering developers 
a way to express "if I tried to synchronize on this thing, would it 
throw", just makes Java less reliable, so we want a way to express 
identity both in the dynamic type system (`instanceof IdentityObject`) 
and the static type system (`<T extends IdentityObject>`).

We also thought, at one point in time, that InlineObject and 
IdentityObject would be a sensible place to put new methods or default 
implementations of Object methods.  However, as the design has evolved, 
the need for this has gone away.  This opens the door to a new 
possibility, which I'd like to evaluate: just have one of them.  (And, 
if we only have one, the move is forced: IdentityObject.)

In this world, we'd just have IdentityObject, which would be viewed as a 
refinement of Object -- "Object, with identity". Identity classes would 
implement it implicitly, as today.  The pedagogy would then be, instead 
of "there are two disjoint kinds of Object", be "Some objects are 
enhanced with identity."  You'd still be able to say

     x instanceof IdentityObject


     void foo(IdentityObject o) { ... }


     class Foo<T extends IdentityObject> { ... }

as a way of detecting the refinement, but not the opposite.  So the 
questions are:

  - Pedagogically, does this help move users to the right mental model, 
or does the symmetric model do a better job?
  - Functionally, is there anything we might do with InlineObject, that 
we would miss?


  - If we take this step, is `IdentityObject` still the best name?

More information about the valhalla-spec-observers mailing list