Java反射泛型 - 通过在编译时传递参数来强制转换?

时间:2011-07-03 21:01:10

标签: java generics reflection instantiation

有以下情况:
给出了一个类,其中包含一个通用字段。是否可以在运行时使用T

的实例实例化该字段
class Root<T>{
   T var;

   Root(){
     //instantiate var with an instance of T here
   }
}

5 个答案:

答案 0 :(得分:4)

如果你有一个扩展Root<T>的类并在其extends子句中设置type参数,那么可以使用getGenericSuperclass()挖掘它。例如Guice uses this approach为注入的类提供类型参数信息。

否则,最好的办法是将Class<T>实例作为构造函数参数传递并使用它。这也将导致更简单的代码,尽管为类的每个实例化提供了更多的样板。

答案 1 :(得分:2)

没有

Java使用类型擦除,因此通用参数在运行时不存在。

答案 2 :(得分:1)

除非在运行时给你T的实例,否则答案是否定的,因为java type erasure。在运行时T实际上被Object替换,因此不存在必要的信息。这就是像List.toArray这样的函数要求您传入一个类型化数组以接收类型化结果的原因。

答案 3 :(得分:1)

由于它在编译时被删除,因此无法在运行时知道T的类型。

但是,您可以向类型为Class<T>的构造函数添加新参数。编译器将确保传递的对象是与您为Class实例指定的T类型对应的Root实例。在构造函数中,您可以使用反射来创建新的T实例:

class Root<T> {

    T var;

    public Root(Class<T> klass) {
        var = klass.newInstance();
    }

}

这假设您的T类型具有默认构造函数。

答案 4 :(得分:0)

没有。如果您确实需要此功能,则需要在构造函数中传入类型。

像这样:

class Root<T> {
  private T var;

  public Root(Class<T> type) {
    var = type.newInstance();
  }
}

这将通过反射创建一个实例。它只有在传入的类具有默认构造函数时才有效。否则你需要扩展这个例子。