[英]Why generic type lookup is not allowed at runtime in Java?
I am trying to see if it possible to get object type for a generic class at run-time in Java. 我试图看看是否有可能在运行时在Java中获取通用类的对象类型。
Example: 例:
public class Member<T> {
private T id;
private T complexityLevel;
// constructor
public Member(T id, T complexityLevel) {
this.id = id;
this.complexityLevel = complexityLevel;
}
// getters and setters goes here
}
Testing.. 测试中
public class TestDrive {
public static void main(String[] args) {
Member<String> memberString = new Member<String>("1", "100");
Member<Integer> memberInteger = new Member<Integer>(1, 100);
Member<Double> memberDouble = new Member<Double>(1.0, 100.00);
List<Member<?>> members = new ArrayList<>();
members.add(memberString);
members.add(memberInteger);
members.add(memberDouble);
for (Member<?> aMember : members) {
if (aMember.getClass().isInstance(String.class))
System.out.printf("String member is found with id: " + aMember.getId());
else if (aMember.getClass().isInstance(Integer.class))
System.out.printf("Integer member is found with id: " + aMember.getId());
else if (aMember.getClass().isInstance(Double.class))
System.out.printf("Double member is found with id: " + aMember.getId());
}
}
}
Is it possible to get wrapper classes ( String
, Integer
, Double
etc) for objects of Member
class at run-time? 是否可以在运行时为
Member
类的对象获取包装器类( String
, Integer
, Double
等)?
You can't determine generic types at runtime due to type erasure . 由于类型擦除,您无法在运行时确定泛型类型。 In order for this information to be preserved after erasure,
Member<T>
would need to take a Class<T>
object in its contructor and hold onto it: 为了使此信息在擦除后得以保留,
Member<T>
将需要在其构造器中使用Class<T>
对象,并保留该对象:
public class Member<T> {
public final Class<T> type;
private T id;
private T complexityLevel;
//constructor
public Member(T id, T complexityLevel, Class<T> type) {
id = id;
this.complexityLevel = complexityLevel;
this.type = type;
}
Then later: 然后再:
Member<String> mString = new Member<String>("id1", "High", String.class);
...
System.out.println(mString.type.getName());
Alternatively, if id
is guaranteed never to be null
, you could use reflection to retrieve the Class
object representing its type: 另外,如果保证
id
永远不会为null
,则可以使用反射来检索表示其类型的Class
对象:
System.out.println(mString.getId().getClass().getName());
Of course getClass() will return a Class<? extends T>
当然getClass()将返回
Class<? extends T>
Class<? extends T>
. Class<? extends T>
。 So if id
is in fact a subclass of T
, you're going to get the name of that class rather than the name of T
. 因此,如果
id
实际上是T
的子类,则将获得该类的名称,而不是T
的名称。
This information (the generic type T) is stripped out during compilation (type erasure). 该信息(通用类型T)在编译(类型擦除)期间被剥离。
Using super type tokens is a moderately painful technique that can apply here. 使用超级类型令牌是一种适度痛苦的技术,可以在这里应用。 Guice's TypeLiteral is an example of this.
Guice的TypeLiteral就是一个例子。
Also, String and Integer are not primitive types. 同样,String和Integer也不是原始类型。 "int" is a primitive.
“ int”是原始的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.