[External] : Re: JEP 401 -- reflection and class literals

Brian Goetz brian.goetz at oracle.com
Wed Jun 30 13:29:57 UTC 2021

Yes, as mentioned, this is where the problem moves to next.   (Did we 
mention that none of the choices are perfect?)

It's not clear it is desirable or practical to try and prohibit 
overloads such as

     m(Point.val x)
     m(Point.ref x)

Even if we tried to, it is a game of whack-a-mole, and the best we could 
do it prevent them when the entire application was consistently compiled 
with `javac`.  But, primitive classes are a JVM feature, the JVM has L 
and Q descriptors, and reflection is *classfile* reflection, not *Java 
language* reflection, as much as we would like to pretend otherwise.  So 
it is a given that eventually reflection will encounter an overload like

     m(int a, float b, Point.ref c)
     m(int a, float b, Point.val c)

Now, what is getMethod() supposed to do?  A fuzzy match?  That's a 
pretty massive departure from what "getMethod" has historically meant.  
(And, for MethodHandles, its worse; lookup is supposed to be precise.)

The reality is these overloads are going to happen, and reflection needs 
sharp enough tools to distinguish between them.

On 6/30/2021 2:53 AM, Gernot Neppert wrote:
> Am So., 27. Juni 2021 um 11:59 Uhr schrieb Remi Forax 
> <forax at univ-mlv.fr <mailto:forax at univ-mlv.fr>>:
>     I think that less is more in that context, we do not have to have
>     a syntax to express the secondary class exactly like we do not
>     allow Foo<String>.class.
>     So instead of allowing Point.ref.class and Point.val.class, i
>     think it's better to have no language support given that we can
>     already write Point.class.asPrimitiveObjectClass().
>     Not having a syntax for Point.ref.class/Point.val.class is
>     important because as you say it's inconsistent, for good, with
>     Point being either an identity class or a primitive object class.
>     Not surfacing that inconsistency in the language make things
>     easier to understand and using methods of java.lang.Class instead
>     make the intent more clear at the expanse of being more verbose.
>     regards,
>     Rémi
> OTOH, proper "value-favoring" primitive classes are *meant to* be 
> passed around by-value, right?
> So, given
> primitive class Point {
> Point transform(Point origin);
> }
> programmers might by deeply puzzled to find out that this will fail:
> /*1*/ Point.class.getMethod("transform", Point.class);
> ...and they are instead expected to write
> /*2*/ Point.class.getMethod("transform", 
> Point.class.asPrimitiveObjectClass());
> Does that really "make the intent more clear", as you claim?
> I think, being able to write
> /*3*/ Point.class.getMethod("transform", Point.val.class);
> would better express the intent.
> However, being able to use /*1*/ without further ado would be even 
> more consistent - which would be automatically possible if the meaning 
> of "T.class" did depend on the "value/reference-favoring"
> characteristic of the primitive type. Back to square one :)

More information about the valhalla-spec-observers mailing list