我收到一个清单,编程如下:public class MyList<T>
。有没有办法使用T变量来获得类的名称(所以我可以从MyList
知道T是字符串,套接字等)?Java泛型 - 获得类?
编辑:没关系,找到答案here。
我收到一个清单,编程如下:public class MyList<T>
。有没有办法使用T变量来获得类的名称(所以我可以从MyList
知道T是字符串,套接字等)?Java泛型 - 获得类?
编辑:没关系,找到答案here。
简答题:你不行。
龙回答:
由于仿制药的方式是用Java实现,通用类型T不能保持在运行。尽管如此,你可以使用私人数据成员:
public class Foo<T>
{
private Class<T> type;
public Foo(Class<T> type) { this.type = type; }
}
您正在看到Type Erasure的结果。从该页面...
当一个泛型类型实例化, 编译器通过 翻译这些类型的技术叫做类型擦除 - 一个 过程,其中编译器消除了输入参数 和类型相关的所有信息 方法中的参数或 方法。类型擦除使Java 使用泛型的应用程序能够与 保持二进制兼容性 Java库和应用程序 在泛型之前创建。
例如,箱<字符串>是 转换为类型框,这是 称为原始类型 - 原始类型是 泛型类或接口名 没有任何类型的参数。 这意味着 ,您无法找到哪种类型的 通用类在 运行时正在使用的对象。
这也看起来像这样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();
}
}
}
这将输出:
字段映射的类型是地图的
字段映射的参数化类型甲
字段映射的具有参数化的类型B的
一旦我尝试在通用DAO重构期间做类似工作,所以我通过了一些类似的代码示例。不记得为什么,但我决定不采用这种方法(我认为它在所有情况下都不能很好地工作,也许课程层次是强制性的)。你的例子确实有效:) +1 P.S.我找到了一些扩展的教程:http://www.artima.com/weblogs/viewpost.jsp?thread=208860 – 2011-01-29 14:38:46
我发现原来的文章,我解除了这个(上面的例子是从我们的工作 - 项目):http://tutorials.jenkov.com/java-reflection/generics.html#fieldtypes文章说这只适用于公共领域,但事实并非如此,你也可以通过反射访问受保护和私人领域(只是使用getDeclaredField而不是getField) – esaj 2011-01-29 14:45:34
我可以通过这种方式获得通用类型的类:
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
我喜欢
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];
}
...
您已经知道答案的解决方案,但你可能要查看http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/TypeLiteral.html – maaartinus 2011-01-29 14:51:20