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