IdentityObject and InlineObject

forax at forax at
Mon Dec 9 21:59:47 UTC 2019

----- Mail original -----
> De: "Maurizio Cimadamore" <maurizio.cimadamore at>
> À: "Brian Goetz" <brian.goetz at>, "Remi Forax" <forax at>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts at>
> Envoyé: Lundi 9 Décembre 2019 15:45:19
> Objet: Re: IdentityObject and InlineObject

> On 06/12/2019 22:28, Brian Goetz wrote:
>>> package java.util;
>>> public class IdentityHashMap<E extends IdentityObject> { ... }
>> This one has an easy out:
>>     public class IdentityHashMap<E extends Object&IdentityObject> { ... }
>> I was hoping your example would be type bounds, since they're easily
>> amenable to this trick (either explicitly, or with compiler help.) Got
>> more?
> Uhm - doing this change is certainly binary compatible (the extra bound
> is erased) - but it's not source compatible - every client using
> IdentityHashMap<Object, ...> would fail to compile now, right?
> E.g. imagine code like this:
> public class Foo {
> public Map<Object, String> cache = new IdentityHashMap<>();
> }
> With the proposed bound change, two things will happen:
> 1) the inferred type of the 'new' expression will change
> 2) the inferred type as of (1) will be incompatible with the type in the
> LHS -> error
> To fix the issue, you have to change the LHS type - if this is a public
> API, this will then trigger more downstream issues (again, not about BC,
> but about source compatibility).

yes, changing a type to use a subtype, Object to IdentityObject is only source compatible if the type is a return type (covariant).
And it has nothing to do with IdentityObject being erased or not, we have the same issue in both cases.

We have choosen to see Object as any (L-word) because there will be few places were Object really means ref instead of any.
But for those locations, changing Object to IdentityObject is not a source compatible change.

So we can,
- not change them, in that case a runtime error will occurs if someone do by example a synchronize on Object.
- introduce IdentityObject and the error will be caught at compile time instead of at runtime, but it's not a source compatible change.

We can try to ease the migration by using the same kind of tricks used we the code was generified but it's less easy because we are moving from an already generified world to another generified world, but trying to couple the migration Object -> IdentityObject with the migration erased generics -> any generics, may offer this kind of opportunity again.

> Maurizio


More information about the valhalla-spec-observers mailing list