简单地:
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
}
class java.lang.Integer
?我知道很多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
。
这种方法基于the 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()
未更改。)
答案 0 :(得分:3)
这有点困难,因为Java故意不能这样做(“类型擦除”)。
变通方法称为super type tokens。关于这一点也有一些线索(如this one或that one)。
答案 1 :(得分:2)
当你有这样的问题时,你应该问问自己,如果没有泛型,你会怎么做?因为任何泛型程序都可以转换为没有泛型的等效程序。 (这种转换称为类型擦除。)因此,如果没有Generics就无法做到,那么你也无法使用Generics。
没有Generics的程序如下所示:
public static class MyClass {
ArrayList mArrayList = new ArrayList();
}
@Test
public final void test() {
MyClass myObject = new MyClass();
Integer result = getParamType( myObject ); // how would you implement getParamType()?
}
答案 2 :(得分:1)
答案 3 :(得分:0)
要了解T
的价值,您需要通过继承MyClass在类型定义中捕获它:
class MyStringClass extends MyClass<String> {}
如果需要,您也可以使用匿名类执行此操作:
MyClass<String> myStringClass = new MyClass<String>{}();
要解析T的值,您可以使用TypeTools:
Class<?> stringType = TypeResolver.resolveRawArgument(MyClass.class, myStringClass.getClass());
assert stringType == String.class;