Instanciando objeto de tipo parámetro

Tengo una clase de plantilla de la siguiente manera:

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

¿Cómo creo una nueva instancia de T en mi clase?

Después del borrado de tipo, todo lo que se sabe sobre T es que es una subclase de Object . Necesita especificar alguna fábrica para crear instancias de T

Un enfoque podría usar un Supplier :

 class MyClass { 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(); } } 

El uso podría verse así:

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

Alternativamente, puede proporcionar un objeto Class y luego usar reflection.

 class MyClass { 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(); } } 

Otro enfoque no reflexivo es usar un patrón híbrido de Builder / Abstract Factory.

En Java efectivo, Joshua Bloch revisa el patrón de Builder en detalle y recomienda una interfaz genérica de Builder:

 public interface Builder { public T build(); } 

Los constructores de hormigón pueden implementar esta interfaz, y las clases externas pueden usar el generador de hormigón para configurar el generador según sea necesario. El constructor se puede pasar a MyClass como un generador Builder .

Usando este patrón, puede obtener nuevas instancias de T , incluso si T tiene parámetros de constructor o requiere configuración adicional. Por supuesto, necesitará alguna forma de pasar el Constructor a MyClass. Si no puede pasar nada a MyClass, entonces Builder y Abstract Factory están fuera.

Esto puede ser más pesado que lo que estás buscando, pero también funcionará. Tenga en cuenta que si toma este enfoque, tendría más sentido inyectar la fábrica en MyClass cuando se construye en lugar de pasarlo a su método cada vez que se invoca.

 interface MyFactory { T newObject(); } class MyClass { T field; public void myMethod(MyFactory factory) { field = factory.newObject() } } 

Si está dispuesto a crear una subclase, puede evitar el borrado también, consulte 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(); }