Java:在运行时检索通用参数值

时间:2009-10-15 08:10:14

标签: java generics

检索泛型类的泛型参数的运行时值的最佳方法是什么?例如:

public class MyClass<T> {

  public void printT() {
    // print the class of T, something like:
    // System.out.println(T.class.getName());
  }

}

所以,如果我打电话

new MyClass<String>().printT() 

它将打印“String”

4 个答案:

答案 0 :(得分:6)

你没有。由于type erasure信息(大部分)在运行时丢失。如果你真的需要这门课,你就是这样做的:

public class MyClass<T> {
  private final Class<T> clazz;

  public MyClass(Class<T> c) {
    if (c == null) {
      throw new NullPointerException("class cannot be null");
    }
    clazz = c;
  }

  public void printT() {
    System.out.println(clazz.getName());
  }
}

然后你就可以访问它了。

答案 1 :(得分:1)

要实现这一点,您需要添加类型信息,因为类型擦除意味着T的类型不可用。

public class MyClass<T> {
  private final Class<T> clazz;
  public MyClass(Class<T> clazz) {
    this.clazz=clazz;
  }

  public void printT() {
    // print the class of T, something like:
    System.out.println(this.clazz);
  }
}

答案 2 :(得分:1)

由于type erasure,Java在运行时没有该信息。在实例化对象时,您需要将类型作为构造函数参数传递给类。有一些图书馆和语言可以帮助您减少输入:Guice can do itScala can do it

答案 3 :(得分:0)

如前所述,由于类型擦除,您无法在该示例中获取类型信息。

但是,您可以重新设计类层次结构,以便拥有通用超类/接口,并使子类直接在其定义中定义类型参数:

package com;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;

public class AAA {
    public static void main(String[] args) throws Exception {
        Object target = new MyClass<Integer>() {}; // child class that explicitly defines superclass type parameter is declared here
        ParameterizedType type = (ParameterizedType) target.getClass().getGenericSuperclass();
        System.out.println(Arrays.toString(type.getActualTypeArguments()));
    }
}

class MyClass<T> {
}