如何获得通用类型参数? [英] How to get the Generic Type Parameter?
问题描述
简单地说:
public static class MyClass< T> {
//如果没有必要,我不想保留T的一个实例。
//它不好,不整齐。
//或者,假设成员的形式如下:
ArrayList< T> mArrayList = new ArrayList< T>();
//获取泛型类型参数的问题仍然存在。
}
@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)new Object())。getClass()); // T
System.out.println // class java.lang.Object
}
如何让代码打印类java.lang.Integer
?
我知道很多stackoverflow线程正在询问(和回答)这个问题。但是他们无法解决这个问题。
- 我不知道为什么有些人需要调用
getGenericSuperclass()
- 因为在这个简单情况下没有继承。 - 我不能将它转换为
ParameterizedType $ c $
$ b $ p $ <$ c $> $ c> System.out.println((ParameterizedType)_myObject.getClass());
//编译错误:无法从Class< capture#11-of?扩展TreeTest2.MyClass> to ParameterizedType
System.out.println((ParameterizedType)_myObject.getClass()。getGenericSuperclass());
//运行时异常:java.lang.ClassCastException
基于@ Thomas的指导,我发现了一种 解决方法 来获取 ; T> 类java.lang.Integer $ c首先,我们创建匿名(它需要是匿名的)子类
MyClass< code
在测试代码中。 (这很奇怪,为什么它只支持子类?)
@Test
public final void test() {
MyClass< Integer> myObject = new MyClass< Integer>(){}; //匿名子类
getParamType(myObject);
$ / code>
然后我们可以使用 getGenericSuperclass() code>方法来获取
类型
然后将其转换为 ParameterizedType
,之后使用 getActualTypeArguments()
:
private static final< T> void getParamType(final MyClass< T> _myObject){
System.out.println(((ParameterizedType)_myObject.getClass()。getGenericSuperclass())。getActualTypeArguments()[0]);
}
完美地打印类java.lang.Integer
。
这是不太好,因为测试代码应该模拟实际情况,用户最有可能将不会继续创建无意义的子类。
这种方法基于 TypeReference类。但我真的不知道如何使用它。我试过 class MyClass< T>扩展了TypeReference< T>
。但我仍然需要创建 MyClass< T>
的子类以使 TypeReference.getType()
打印 class java.lang.Integer
。
请帮忙,谢谢任何输入,因为最好的方法还没有出现。
基于上述解决方法的进一步问题:为什么只有匿名子类有效?
public static class SubMyClass< T>扩展MyClass< T> {}
@Test
public final void test(){
MyClass< Integer> myObject = new MyClass< Integer>(){}; //匿名子类
getParamType(myObject); // class java.lang.Integer
MyClass< Integer> mySubObject = new SubMyClass< Integer>(); //命名的子类
getParamType(mySubObject); // T
( MyClass
和 getParamType()
不变。)
因为Java故意无法做到这一点(类型擦除)。
解决方法称为超级类型令牌。还有一些关于此的线索(如这一个或那一个)。
Simply:
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
}
How to let the code print class java.lang.Integer
?
i know quite a few of stackoverflow threads are asking (and answering) about this. Yet they couldn't solve this question.
- i don't know why some need to call
getGenericSuperclass()
- as there is no inheritance involved in this simple case. - And i can't cast it to
ParameterizedType
as well.
.
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
Based on @Thomas's guide, i have found a work-around way to get class java.lang.Integer
.
First, we create an anonymous (it need to be anonymous) sub-class of MyClass<T>
in the testing code. (Which is weird. Why it only support sub-classes?)
@Test
public final void test() {
MyClass<Integer> myObject = new MyClass<Integer>() {}; // Anonymous sub-class
getParamType( myObject );
}
Then we can use the getGenericSuperclass()
method to get a Type
then cast it to ParameterizedType
and afterwards uses getActualTypeArguments()
:
private static final <T> void getParamType(final MyClass<T> _myObject) {
System.out.println( ((ParameterizedType) _myObject.getClass().getGenericSuperclass()).getActualTypeArguments()[0] );
}
It perfectly prints class java.lang.Integer
.
This is not-so-good because the testing codes should simulate the actual situation, where users most likely won't keep creating meaningless sub-classes.
This approach is based on the idea of the TypeReference class. But i don't really know how to use it. I have tried class MyClass<T> extends TypeReference<T>
. But i still have to create sub-class of MyClass<T>
to have TypeReference.getType()
prints class java.lang.Integer
.
Please help, and thanks for any inputs, as the best approach is not here yet.
A further question based on the above workaround: Why only anonymous sub-class works?
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
and getParamType()
unchanged.)
This is sort of difficult, because Java deliberately can't do that ("type erasure").
The work-around is called super type tokens. There are also some threads on SO about that (like this one or that one).
这篇关于如何获得通用类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!