2011-04-26 112 views
11

如何获得泛型类型的“真实”类?获得“真实”类的泛型类型

例如:

public class MyClass<T> { 
    public void method(){ 
     //something 

     System.out.println(T.class) //causes a compile error, I wont the class name 

     //something 
    } 
} 

如果T =整数

输出:

java.lang.Integer 

如果T =字符串

输出:

java.lang.String 

谢谢

+2

你可以通过反思得到这个。但是,请记住,如果您必须根据其泛型类型对数据进行不同的处理,那么您做错了。你不应该。如果你确实需要,它不像你想象的那么通用,这意味着你的班级有问题。 – corsiKa 2011-04-26 01:58:27

+1

@glowcoder:这可能是有效的,我已经运行到自己的一个示例是访问泛型类型的静态属性。一种解决方法是定义一个你永远不会真正使用的实例,比如'T obj;',所以你稍后可以说'obj.static_property'。此外,你可以做'((T)null).static_property'。 – mellamokb 2011-04-26 02:04:08

+0

如果您有该类型的对象,则可以在该对象上调用getClass方法。不知道这是否有帮助。 – 2011-04-26 02:04:13

回答

21

如果您有类型T的实例变量在你的类,它恰好设置,那么你可以打印类变量。

public class Test<T> { 

    T var; 

    public static void main(String[] args) { 
     Test<Integer> a = new Test<Integer>(); 
     System.out.println(a.boo()); 
     a.setVar(new Integer(10)); 
     System.out.println(a.boo()); 
    } 

    public String boo() { 
     if (var == null) { 
      return "Don't know yet"; 
     } 
     return var.getClass().getSimpleName(); 
    } 

    public void setVar(T var) { 
     this.var = var; 
    } 

    public T getVar() { 
     return var; 
    } 
} 
+0

考虑将var设置为类X的实例,其中X扩展了T. boo()将打印X而不是T. – jackrabbit 2011-10-16 12:49:42

12

你不行。在编译时将信息从代码中剥离出来,这个过程称为类型擦除。欲了解更多,请看这里:Type Erasure

编辑:对不起,我的坏,信息不会在运行时加载。

+1

好吧,不是特别真实的,它在类文件中作为类或方法属性。它只是没有在运行时加载到内存中。 – MeBigFatGuy 2011-04-26 02:00:14

+0

@MeBigFatGuy:谢谢!让我纠正我上面所说的。 – 2011-04-26 02:01:40

4

正如其他人所解释的,你不能干这种方式可能更多,但这是它是如何在Java中实现一般。

public class MyClass<T> { 
    public void method(Class<T> clazz) { 
     // something 

     System.out.println(clazz.getName()); 

     // something 
    } 
} 

,你使用这样

new MyClass<String>().method(String.class); 
0

注意,办法依托“的getClass()”上与通用型接收的情况下会得到对象,这不一定是泛型类型的实际类型 - 这将是类型,它的来电者知道这个实例。

例如,考虑调用者通过接口处理对象的情况;当传递到泛型构造时,泛型将是接口,而不是实例的实际类。

请看下面的例子“配对”类,它允许两个对象的引用,通过一个POJO返回:

public class Pair<U,V> 
{ 
    public final U first; 
    public final V second; 
    public static <U,V> Pair<U,V> of (U first, V second) 
    { 
     return new Pair<U,V> (first, second); 
    } 
    protected Pair (U first, V second) 
    { 
     this.first = first; 
     this.second = second; 
    } 
} 

我们正在考虑如何修改“Pair.of()工厂函数返回一个Comparable Pair派生类,如果U和V都是Comparable。然而,虽然我们可以通过instanceof判断'first'和'second'是否可以相比较,但我们不知道'U'和'V'本身是可比较的。

为此,Pair对返回的Pair的确切类型。()必须取决于泛型类型,而不是的实际参数类型。