Inconsistency in Constructor.getGenericParameterTypes()
Joe Darcy
joe.darcy at oracle.com
Fri Feb 26 21:38:48 UTC 2021
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 <odrotbohm at vmware.com>
> Betreff: Inconsistency in Constructor.getGenericParameterTypes()
> Datum: 25. Februar 2021 um 10:03:12 MEZ
> An: jdk-dev at 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) {}
> }
> }
>
More information about the core-libs-dev
mailing list