[External] : Re: JEP 401 -- reflection and class literals
forax at univ-mlv.fr
forax at univ-mlv.fr
Wed Jun 30 14:46:07 UTC 2021
> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Gernot Neppert" <mcnepp02 at googlemail.com>, "Valhalla Expert Group
> Observers" <valhalla-spec-observers at openjdk.java.net>, "Remi Forax"
> <forax at univ-mlv.fr>
> Sent: Mercredi 30 Juin 2021 15:29:57
> Subject: Re: [External] : Re: JEP 401 -- reflection and class literals
> 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.
I don't follow you here,
getField() and getMethod() already do fuzzy matching, you can have more than one field with the same name and you can have several methods with the same name but different return types.
In particular, getMethod() tries to avoid to select a bridge if there is a non bridge equivalent.
> (And, for MethodHandles, its worse; lookup is supposed to be precise.)
yes, lookup.find*() is precise because the semantics is the same as the equivalent bytecode (invoke*).
> The reality is these overloads are going to happen, and reflection needs sharp
> enough tools to distinguish between them.
Given that we want to retrofit Integer to be the ref of int, these overloads already exist.
So reflection can still do fuzzy matching but the selection algorithm has to prefer precise matching to fuzzy match.
Rémi
> On 6/30/2021 2:53 AM, Gernot Neppert wrote:
>> Am So., 27. Juni 2021 um 11:59 Uhr schrieb Remi Forax < [
>> mailto:forax at univ-mlv.fr | 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