RefObject and ValObject

Brian Goetz brian.goetz at
Mon Apr 15 13:26:44 UTC 2019

> But the other concerns remain, e.g. as to the fact that the boundary between reinterpreted types (Object as RefObject) and non-reinterpreted types (Object as top type) seems very fuzzy.

Right, which is why we’re still searching for an answer :) 

We really, really want to be able to represent ref/val-ness in the type system.  Why?  Ignoring pedagogical concerns (which are significant): 

 - If certain operations (e.g., locking) are partial, we want to be able to provide a way to ask if the operation could succeed.  Such as:

    if (x instanceof RefObejct) { … lock on x … }

Saying “lock, and hope it doesn’t throw” is not a very good answer.  We already have a tool for querying the dynamic type of an object — instanceof.

 - Saying that a method should only accept reference objects should be something expressible in the method signature, as in

    m(RefObject o) { … }

Types are how we do that.

 - Similarly, we might want to express the above constraint generically; again, types are the way we do that:

    class Foo<T extends RefObject> { }

And, Q-world already taught us that we wanted to retain Object as the top type.  This mean, necessarily, that Object gets a little weirder; it takes on some partly-class, partly-interface behavior.  

Here’s an idea: What if we migrated `Object` to be an abstract class?  The casualty would be the code that says `new Object()`.  While there’s certainly a lot of it out there, perhaps this is something amenable to migration:

 - At the source level, for N versions, `new Object()` gets a warning that says “I’ll pretend you said `Object.newLockInstance()` or something.  
 - At the bytemode level, for M versions, we do something similar, likely for M > N.  

We can start this now, before Valhalla even previews.  

More information about the valhalla-spec-observers mailing list