Inline Record vs JLS / Reflection

Dan Smith daniel.smith at
Wed Dec 16 18:07:44 UTC 2020

> On Dec 2, 2020, at 5:09 AM, Remi Forax <forax at> wrote:
> Hi all,
> currently an inline record like this
>  public @__inline__ record IntBox(int value) {
>  }
> generates two classes, IntBox and IntBox$ref, IntBox being the record itself and IntBox$ref being the abstract class representing the nullable version of an inline that inherits from java.lang.Record.
> This doesn't works well with the JLS view / the reflection API because for them a record class is a direct super class of java.lang.Record while in this case java.lang.Record is not a direct super type.
> I believe the reflection should be changed to say that a record is a subtype of java.lang.Record.

Yes, the fact that the superclass of a primitive record class is *not* java.lang.Record is surprising and potentially breaks some things.

This is one manifestation of the problem, but more generally it will be surprising to reflection clients that a class that 'extends Foo' (where Foo is a primitive-compatible abstract class) doesn't have 'Foo' as its superclass.

I don't think we have a good answer right now, but it's something we will want to address at some point. A solution would have to look like one of:

- Ask clients (e.g., "is this a record?" code) to adapt to the presence of the '$ref' class
- Modify reflection to hide the '$ref' superclass somehow
- Change the translation strategy to not disrupt the superclass hierarchy

More information about the valhalla-spec-observers mailing list