Inconsistency in Constructor.getGenericParameterTypes()

Oliver Drotbohm odrotbohm at vmware.com
Thu Feb 25 09:03:13 UTC 2021


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 jdk-dev mailing list