2011-01-29 143 views
63

我收到一个清单,编程如下:public class MyList<T>。有没有办法使用T变量来获得类的名称(所以我可以从MyList知道T是字符串,套接字等)?Java泛型 - 获得类?

编辑:没关系,找到答案here

+0

您已经知道答案的解决方案,但你可能要查看http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/inject/TypeLiteral.html – maaartinus 2011-01-29 14:51:20

回答

89

简答题:你不行。

龙回答

由于仿制药的方式是用Java实现,通用类型T不能保持在运行。尽管如此,你可以使用私人数据成员:

public class Foo<T> 
{ 
    private Class<T> type; 

    public Foo(Class<T> type) { this.type = type; } 
} 
24

您正在看到Type Erasure的结果。从该页面...

当一个泛型类型实例化, 编译器通过 翻译这些类型的技术叫做类型擦除 - 一个 过程,其中编译器消除了输入参数 和类型相关的所有信息 方法中的参数或 方法。类型擦除使Java 使用泛型的应用程序能够与 保持二进制兼容性 Java库和应用程序 在泛型之前创建。

例如,箱<字符串>是 转换为类型框,这是 称为原始类型 - 原始类型是 泛型类或接口名 没有任何类型的参数。 这意味着 ,您无法找到哪种类型的 通用类在 运行时正在使用的对象。

这也看起来像这样question具有pretty good answer as well

3

我不是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的

+0

一旦我尝试在通用DAO重构期间做类似工作,所以我通过了一些类似的代码示例。不记得为什么,但我决定不采用这种方法(我认为它在所有情况下都不能很好地工作,也许课程层次是强制性的)。你的例子确实有效:) +1 P.S.我找到了一些扩展的教程:http://www.artima.com/weblogs/viewpost.jsp?thread=208860 – 2011-01-29 14:38:46

+0

我发现原来的文章,我解除了这个(上面的例子是从我们的工作 - 项目):http://tutorials.jenkov.com/java-reflection/generics.html#fieldtypes文章说这只适用于公共领域,但事实并非如此,你也可以通过反射访问受保护和私人领域(只是使用getDeclaredField而不是getField) – esaj 2011-01-29 14:45:34