ZeD*_*ino 20 java generics types type-erasure
我见过类似的问题,但他们没有多大帮助.
例如,我有这个通用类:
public class ContainerTest<T>
{
public void doSomething()
{
//I want here to determinate the Class of the type argument (In this case String)
}
}
Run Code Online (Sandbox Code Playgroud)
和另一个使用此容器类的类
public class TestCase
{
private ContainerTest<String> containerTest;
public void someMethod()
{
containerTest.doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
是否有可能在方法doSomething()中确定类型参数的类而没有在ContainerTest类中使用显式类型变量/字段或任何构造函数?
更新:更改ContainerTest类的格式
Did*_*r L 13
唯一的方法是将类存储在实例变量中,并将其作为构造函数的参数:
public class ContainerTest<T>
{
private Class<T> tClass;
public ContainerTest(Class<T> tClass) {
this.tCLass = tClass;
}
public void doSomething()
{
//access tClass here
}
}
Run Code Online (Sandbox Code Playgroud)
ded*_*dek 10
如果您对反射方式感兴趣,我在这篇很棒的文章中找到了部分解决方案:http: //www.artima.com/weblogs/viewpost.jsp?thread = 208860
简而言之,您可以使用java.lang.Class.getGenericSuperclass()和java.lang.reflect.ParameterizedType.getActualTypeArguments()方法,但您必须子类化一些父超类.
以下代码段适用于直接扩展超类的类AbstractUserType.有关更一般的解决方案,请参阅参考文章
import java.lang.reflect.ParameterizedType;
public class AbstractUserType<T> {
public Class<T> returnedClass() {
ParameterizedType parameterizedType = (ParameterizedType) getClass()
.getGenericSuperclass();
@SuppressWarnings("unchecked")
Class<T> ret = (Class<T>) parameterizedType.getActualTypeArguments()[0];
return ret;
}
public static void main(String[] args) {
AbstractUserType<String> myVar = new AbstractUserType<String>() {};
System.err.println(myVar.returnedClass());
}
}
Run Code Online (Sandbox Code Playgroud)
从类中获取Generic Type参数没有"干净"的方法.相反,常见的模式是将通用类的类传递给构造函数,并将其作为内部属性juste保存,如java.util.EnumMap实现中所做的那样.
http://docs.oracle.com/javase/1.5.0/docs/api/java/util/EnumMap.html http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk /6-b14/java/util/EnumMap.java
public class ContainerTest<T> {
Class<T> type;
T t;
public ContainerTest(Class<T> type) {
this.type = type;
}
public void setT(T t) {
this.t = t;
}
public T getT() {
return t;
}
public void doSomething() {
//There you can use "type" property.
}
}
Run Code Online (Sandbox Code Playgroud)
不。由于类型擦除,这是不可能的(类型参数被编译为 Object + 类型转换)。如果您确实需要在运行时了解/强制执行该类型,您可以存储对对象的引用Class。
public class ContainerTest<T> {
private final Class<T> klass;
private final List<T> list = new ArrayList<T>();
ContainerTest(Class<T> klass) {
this.klass = klass;
}
Class<T> getElementClass() {
return klass;
}
void add(T t) {
//klass.cast forces a runtime cast operation
list.add(klass.cast(t));
}
}
Run Code Online (Sandbox Code Playgroud)
使用:
ContainerTest<String> c = new ContainerTest<>(String.class);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
42408 次 |
| 最近记录: |