实例化types参数的对象
我有一个模板类如下:
class MyClass<T> { T field; public void myMethod() { field = new T(); // gives compiler error } }
如何在我的课堂上创build一个新的T实例?
types擦除之后,所有关于T
就是它是Object
一些子类。 您需要指定一些工厂来创buildT
实例。
一种方法可以使用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>
对象,然后使用reflection。
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(); } }
另一个不reflection的方法是使用混合的Builder / Abstract Factory模式。
在Effective Java中,Joshua Bloch详细介绍了Builder模式,并提倡通用的Builder接口:
public interface Builder<T> { public T build(); }
混凝土build设者可以实现这个接口,外部类可以使用具体的build造者根据需要configurationBuilder。 构build器可以作为Builder<T>
传递给MyClass。
使用此模式,即使T
具有构造函数参数或需要其他configuration,也可以获得T
新实例。 当然,你需要一些方法将Builder传递给MyClass。 如果你不能传递任何东西到MyClass中,那么Builder和Abstract Factory就出来了。
这可能比你想要的更重量级,但它也可以工作。 请注意,如果采取这种方法,在构build时将工厂注入MyClass会更有意义,而不是在每次调用时将其传递到您的方法。
interface MyFactory<T> { T newObject(); } class MyClass<T> { T field; public void myMethod(MyFactory<T> factory) { field = factory.newObject() } }
如果你愿意子类化,你也可以避免擦除,看看http://www.artima.com/weblogs/viewpost.jsp?thread=208860
Class classOfT
try { t = classOfT.newInstance();//new T(); NOTE: type parameter T cannot be instantiated directly } catch (Exception e) { e.printStackTrace(); }