通过在编译时传递参数来进行Java反射



存在以下情况:
给出了一个类,其中有一个泛型字段。是否可以在运行时用T的实例实例化该字段?

class Root<T>{
   T var;
   Root(){
     //instantiate var with an instance of T here
   }
}

如果您有一个扩展Root<T>并在其extends子句中设置类型参数的类,那么可以使用getGenericSuperclass((来挖掘它。例如,Guice使用这种方法向注入的类提供类型参数信息。

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

否。

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

除非在运行时为您提供T的实例,否则由于java类型的擦除,答案是否定的。在运行时,T实际上被Object替换,因此不存在必要的信息。这就是像List.toArray这样的函数需要传入类型化数组才能接收类型化结果的原因。

在运行时无法知道T的类型,因为它在编译时被擦除。

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

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

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

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

像这样:

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

这将通过反射创建一个实例。只有当传入的类具有默认构造函数时,它才会起作用。否则,您将需要扩展示例。

相关内容

  • 没有找到相关文章

最新更新