Hi Remi,

As package level statement would be helpful as long as it was linked to from specific types and methods (as java.lang.Class and java.lang.Package are part of core reflection but not the java.lang.reflect package).

As you state, core reflection is *mostly* a view of what is represented in the class file. However, the class file in general does not present sufficient information in all cases to recover a source-file view of the world even as an option. For example, as a compiler-internal contract javac had added two additional parameters to the private constructors of enums. Other Java compilers are required to do this and javac could, in principle, change this implementation detail at any time. There is no MANDATED or SYNTHETIC bit (see javax.lang.model.util.Elements.Origin) that can be used to reliably tease apart what is going on. The package-level specs of javax.lang.model.element discuss analogous issue for the language model API.

In any case, I've filed

    JDK-8262807: Note assumptions of core reflection modeling and parameter handling

for core reflection.

Thanks,

-Joe

On 3/1/2021 2:16 PM, Remi Forax wrote:
Hi Joe,
i think the overview of the package java.lang.reflect should discuss the fact 
that the reflection view is what is stored in the classfile, not exactly a 
reflection of the java code.

So depending on what you are requesting, you can see synthetic parameters 
generated by javac or only the Java view because the Java view is directly 
stored in an attributes like with generics

Rémi

----- Mail original -----
De: "joe darcy" <joe.da...@oracle.com>
À: "Oliver Drotbohm" <odrotb...@vmware.com>
Cc: "core-libs-dev" <core-libs-dev@openjdk.java.net>
Envoyé: Lundi 1 Mars 2021 22:35:59
Objet: Re: Inconsistency in Constructor.getGenericParameterTypes()
Hi Oliver,

Perhaps the time has come to make a run at discussing this situation in
the javadoc. One challenge in writing this material up is to phrase and
structure the text so it offers a net-clarification of the situation. In
other words, to not distract or confuse most readers on what is usually
a tricky detail.

The @apiNote javadoc tag offers a mechanism to separate such discussion.

Thanks,

-Joe

On 2/26/2021 2:20 PM, Oliver Drotbohm wrote:
Hi Joe,

thanks for the explanation. We switched to rather iterating over
….getParameters() and take it from there. Do you think it makes sense to leave
a note about this in the Javadoc?

Cheers,
Ollie

Am 26.02.2021 um 22:38 schrieb Joe Darcy <joe.da...@oracle.com>:

Hello Oliver,

This is long-standing if surprising and under-documented behavior.

The getGenericFoo methods, when generic type information is present, give a
source-level view of the element. At a source level, the implicit outer this
parameter is not present and thus omitted by
constructor.getGenericParameterTypes for the constructor in question.

HTH,

-Joe

On 2/26/2021 5:41 AM, Oliver Drotbohm wrote:
Previously sent to the wrong list. Sorry for the double post.

Von: Oliver Drotbohm <odrotb...@vmware.com>
Betreff: Inconsistency in Constructor.getGenericParameterTypes()
Datum: 25. Februar 2021 um 10:03:12 MEZ
An: jdk-...@openjdk.java.net

Hi all,

we've just ran into the following issue: for a non-static, generic inner class
with a constructor declaring a generic parameter, a call to
constructor.getGenericParameterTypes() does not return the enclosing class
parameter type. Is that by intention? If so, what's the reasoning behind that?

Here's a the output of a reproducer (below):

static class StaticGeneric<T> - names: value, string
static class StaticGeneric<T> - parameters: [class java.lang.Object, class
java.lang.String]
static class StaticGeneric<T> - generic parameters: [T, class java.lang.String]

class NonStaticGeneric<T> - names: this$0, value, String
class NonStaticGeneric<T> - parameters: [class Sample, class java.lang.Object,
class java.lang.String]
class NonStaticGeneric<T> - generic parameters: [T, class java.lang.String]

class NonStaticNonGeneric - names: this$0, String
class NonStaticNonGeneric - parameters: [class Sample, class java.lang.String]
class NonStaticNonGeneric - generic parameters: [class Sample, class
java.lang.String]

Note how the constructor of the NonStaticGeneric<T> type exposes three parameter
names, three parameter types but omits the enclosing class parameter in the
list of generic parameter types.

Tested on JDK 8 to 15. Same behavior.

Cheers,
Ollie


class Sample {

        public static void main(String[] args) {

                Constructor<?> first = 
StaticGeneric.class.getDeclaredConstructors()[0];

                System.out.println("static class StaticGeneric<T> - names: "
                                +
                                
Arrays.stream(first.getParameters()).map(Parameter::getName).collect(Collectors.joining(",
                                ")));
                System.out.println("static class StaticGeneric<T> - parameters: 
" +
                Arrays.toString(first.getParameterTypes()));
                System.out.println(
                                "static class StaticGeneric<T> - generic parameters: 
" +
                                
Arrays.toString(first.getGenericParameterTypes()));

                System.out.println();

                Constructor<?> second = 
NonStaticGeneric.class.getDeclaredConstructors()[0];
                System.out.println("class NonStaticGeneric<T> - names: "
                                +
                                
Arrays.stream(second.getParameters()).map(Parameter::getName).collect(Collectors.joining(",
                                ")));
                System.out.println("class NonStaticGeneric<T> - parameters: " +
                Arrays.toString(second.getParameterTypes()));
                System.out
                                .println(
                                                "class NonStaticGeneric<T> - generic 
parameters: " +
                                                
Arrays.toString(second.getGenericParameterTypes()));

                System.out.println();

                Constructor<?> third = 
NonStaticNonGeneric.class.getDeclaredConstructors()[0];
                System.out.println("class NonStaticNonGeneric - names: "
                                +
                                
Arrays.stream(third.getParameters()).map(Parameter::getName).collect(Collectors.joining(",
                                ")));
                System.out.println("class NonStaticNonGeneric - parameters: " +
                Arrays.toString(third.getParameterTypes()));
                System.out
                                .println(
                                                "class NonStaticNonGeneric - generic 
parameters: " +
                                                
Arrays.toString(third.getGenericParameterTypes()));
        }

        static class StaticGeneric<T> {
                StaticGeneric(T value, String string) {}
        }

        class NonStaticGeneric<T> {
                NonStaticGeneric(T value, String String) {}
        }

        class NonStaticNonGeneric {
                NonStaticNonGeneric(String String) {}
        }
}

Reply via email to