简单来说:
public static class MyClass<T> {
// i don't want to keep an instance of T, if it is not necessary.
// and it is not nice, not neat.
// Or, let's say, the member are in the form of :
ArrayList<T> mArrayList = new ArrayList<T>();
// the problem of getting the generic type parameter is still present.
}
@Test
public final void test() {
MyClass<Integer> myObject = new MyClass<Integer>();
getParamType( myObject );
}
private static final <T> void getParamType(final MyClass<T> _myObject) {
System.out.println(_myObject.getClass().getTypeParameters()[0]); // T
System.out.println(((T) new Object()).getClass()); // class java.lang.Object
}
如何让代码打印出?
我知道stackoverflow上有很多关于这个问题的帖子(并回答),但它们都不能解决这个问题。
- 我不知道为什么有些人需要调用
getGenericSuperclass()
- 因为在这种简单情况下没有涉及到继承。 - 而且我也无法将其强制转换为
ParameterizedType
。
.
System.out.println((ParameterizedType) _myObject.getClass());
// Compile Error: Cannot cast from Class<capture#11-of ? extends TreeTest2.MyClass> to ParameterizedType
System.out.println((ParameterizedType) _myObject.getClass().getGenericSuperclass());
// Runtime Exception: java.lang.ClassCastException
根据@Thomas的指南,我找到了一个解决方法来获取class java.lang.Integer
。
首先,在测试代码中,我们创建一个匿名的(必须是匿名的)MyClass<T>
子类。(这很奇怪。为什么它只支持子类?)
@Test
public final void test() {
MyClass<Integer> myObject = new MyClass<Integer>() {}; // Anonymous sub-class
getParamType( myObject );
}
然后我们可以使用getGenericSuperclass()
方法获取一个Type
,然后将其转换为ParameterizedType
,接着使用getActualTypeArguments()
:
private static final <T> void getParamType(final MyClass<T> _myObject) {
System.out.println( ((ParameterizedType) _myObject.getClass().getGenericSuperclass()).getActualTypeArguments()[0] );
}
它可以完美地打印出class java.lang.Integer
。
这不是很好,因为测试代码应该模拟实际情况,用户最可能不会不停地创建无意义的子类。
这种方法基于TypeReference class的想法。但我不知道如何使用它。我已经尝试过class MyClass<T> extends TypeReference<T>
。但我仍然需要创建MyClass<T>
的子类才能使TypeReference.getType()
打印class java.lang.Integer
。
请帮忙,感谢任何的输入,因为最佳方法还没有出现。
基于上述解决方法的进一步问题:为什么只有匿名子类起作用?
public static class SubMyClass<T> extends MyClass<T>{}
@Test
public final void test() {
MyClass<Integer> myObject = new MyClass<Integer>() {}; // Anonymous sub-class
getParamType( myObject ); // class java.lang.Integer
MyClass<Integer> mySubObject = new SubMyClass<Integer>(); // named sub-class
getParamType( mySubObject ); // T
}
(
MyClass
和getParamType()
保持不变。)
TypeReference
类对我来说是新的。我可以这样理解TypeReference<T>
为什么可以获取其T
,因为 (1) 它是抽象的,因此强制继承,以及 (2) 只有Type java.lang.Class.getGenericSuperclass()
可以转换为ParameterizedType
,因此我们可以使用getActualTypeArguments
? - midniteType java.lang.Class.getGeneric_____class()
这样的方法,我们就可以使用((ParameterizedType) getClass().getGeneric____class()).getActualTypeArguments()
,那将是非常好的,不是吗?顺便问一下,为什么Java只有返回Type
的“获取超类”方法呢? - midniteTypeReference
获取class java.lang.Integer
?我可以通过new TypeReference<List<String>>() {}.getType()
来获得java.util.List<java.lang.String>
(但这并不有用,因为它并没有从对象中获取)。然后我使用class MyClass<T> extends TypeReference<T>
,通过myObject.getType()
只能得到T
。感谢指引我这个方向。请帮助我更进一步。 - midnite