实例化类型参数的对象

新手上路,请多包涵

我有一个模板类如下:

 class MyClass<T>
{
    T field;
    public void myMethod()
    {
       field = new T(); // gives compiler error
    }
}

如何在我的类中创建 T 的新实例?

原文由 Mercurious 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 332
2 个回答

类型擦除后,所有关于 T 的已知信息是它是 Object 的某个子类。您需要指定一些工厂来创建 T 的实例。

一种方法可以使用 Supplier<T>

 class MyClass<T> {

  private final Supplier<? extends T> ctor;

  private T field;

  MyClass(Supplier<? extends T> ctor) {
    this.ctor = Objects.requireNonNull(ctor);
  }

  public void myMethod() {
    field = ctor.get();
  }

}

用法可能如下所示:

 MyClass<StringBuilder> it = new MyClass<>(StringBuilder::new);

或者,您可以提供一个 Class<T> 对象,然后使用反射。

 class MyClass<T> {

  private final Constructor<? extends T> ctor;

  private T field;

  MyClass(Class<? extends T> impl) throws NoSuchMethodException {
    this.ctor = impl.getConstructor();
  }

  public void myMethod() throws Exception {
    field = ctor.newInstance();
  }

}

原文由 erickson 发布,翻译遵循 CC BY-SA 3.0 许可协议

另一种非反射性方法是使用混合构建器/抽象工厂模式。

在 Effective Java 中,Joshua Bloch 详细介绍了 Builder 模式,并提倡通用的 Builder 接口:

 public interface Builder<T> {
  public T build();
}

具体构建器可以实现该接口,外部类可以使用具体构建器根据需要配置Builder。构建器可以作为 Builder<T> 传递给 MyClass。

使用此模式,您可以获得 T 的新实例,即使 T 具有构造函数参数或需要额外的配置。当然,您需要某种方式将 Builder 传递到 MyClass。如果你不能将任何东西传递给 MyClass,那么 Builder 和 Abstract Factory 就出局了。

原文由 InverseFalcon 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题