【发布时间】:2011-06-17 18:07:57
【问题描述】:
我有一个列表,编程如下:public class MyList<T>。有什么方法可以使用 T 变量来获取类的名称(这样我就可以从 MyList 中知道 T 是 String、Socket 等)吗?
编辑:没关系,找到答案here。
【问题讨论】:
我有一个列表,编程如下:public class MyList<T>。有什么方法可以使用 T 变量来获取类的名称(这样我就可以从 MyList 中知道 T 是 String、Socket 等)吗?
编辑:没关系,找到答案here。
【问题讨论】:
简答:你不能。
长答案:
由于泛型在 Java 中的实现方式,泛型类型 T 不会在运行时保留。不过,您可以使用私有数据成员:
public class Foo<T>
{
private Class<T> type;
public Foo(Class<T> type) { this.type = type; }
}
使用示例:
Foo<Integer> test = new Foo<Integer>(Integer.class);
【讨论】:
我喜欢来自
的解决方案http://www.nautsch.net/2008/10/28/class-von-type-parameter-java-generics/
public class Dada<T> {
private Class<T> typeOfT;
@SuppressWarnings("unchecked")
public Dada() {
this.typeOfT = (Class<T>)
((ParameterizedType)getClass()
.getGenericSuperclass())
.getActualTypeArguments()[0];
}
...
【讨论】:
您正在看到Type Erasure 的结果。从那个页面...
当一个泛型类型被实例化时, 编译器通过 一种称为类型擦除的技术—— 编译器删除所有的过程 类型参数相关信息 并在类中键入参数或 方法。类型擦除启用 Java 使用泛型的应用程序 保持二进制兼容性 Java 库和应用程序 是在泛型之前创建的。
例如,Box
是 翻译成 Box 类型,即 称为原始类型——原始类型是 泛型类或接口名称 没有任何类型参数。 这意味着 你不知道是什么类型的 泛型类正在使用的对象 运行时。
这也看起来像这样的question,其中有一个pretty good answer as well。
【讨论】:
我不能 100% 确定这是否适用于所有情况(至少需要 Java 1.5):
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
public class Main
{
public class A
{
}
public class B extends A
{
}
public Map<A, B> map = new HashMap<Main.A, Main.B>();
public static void main(String[] args)
{
try
{
Field field = Main.class.getField("map");
System.out.println("Field " + field.getName() + " is of type " + field.getType().getSimpleName());
Type genericType = field.getGenericType();
if(genericType instanceof ParameterizedType)
{
ParameterizedType type = (ParameterizedType) genericType;
Type[] typeArguments = type.getActualTypeArguments();
for(Type typeArgument : typeArguments)
{
Class<?> classType = ((Class<?>)typeArgument);
System.out.println("Field " + field.getName() + " has a parameterized type of " + classType.getSimpleName());
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
这将输出:
字段映射的类型为 Map
字段映射的参数化类型为 A
字段映射的参数化类型为 B
【讨论】:
我可以通过这种方式获得泛型类型的 Class:
class MyList<T> {
Class<T> clazz = (Class<T>) DAOUtil.getTypeArguments(MyList.class, this.getClass()).get(0);
}
更多解释:http://www.artima.com/weblogs/viewpost.jsp?thread=208860
【讨论】: