为什么 Java 运行时不允许泛型类型查找?
我想看看是否有可能在 Java 运行时获取泛型类的对象类型。
示例:
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
}
测试..
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());
}
}
}
是否可以获得包装类(String
、Integer
、Double< /code> 等)对于运行时
Member
类的对象?
I am trying to see if it possible to get object type for a generic class at run-time in 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于类型擦除,您无法在运行时确定泛型类型。为了在擦除后保留此信息,
Member
需要在其构造函数中获取一个Class
对象并保留它:然后:
或者,如果保证
id
永远不会为null
,您可以使用反射来检索表示其类型的Class
对象:当然 getClass() 将返回一个
类
。因此,如果id
实际上是T
的子类,您将获得该类的名称而不是T
的名称。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 aClass<T>
object in its contructor and hold onto it:Then later:
Alternatively, if
id
is guaranteed never to benull
, you could use reflection to retrieve theClass
object representing its type:Of course getClass() will return a
Class<? extends T>
. So ifid
is in fact a subclass ofT
, you're going to get the name of that class rather than the name ofT
.此信息(泛型类型 T)在编译期间被删除(类型擦除)。
使用 超级类型标记 是一种中等痛苦的技术,可以应用于此处。 Guice 的 TypeLiteral 就是一个示例。
此外,String 和 Integer 不是原始类型。 “int”是一个原语。
This information (the generic type T) is stripped out during compilation (type erasure).
Using super type tokens is a moderately painful technique that can apply here. Guice's TypeLiteral is an example of this.
Also, String and Integer are not primitive types. "int" is a primitive.