2008-11-18 7 views

Respuesta

57

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

Un enfoque podría utilizar un 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(); 
    } 

} 

uso podría tener este aspecto:

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

Alternativamente, se puede proporcionar un objeto Class<T>, y luego utilizar la reflexión.

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

} 
+0

Lo que el paquete 'Supplier' se encuentra en? 'MyClass (Clase impl)' debe declarar 'throws NoSuchMethodException' para compilarse. Desafortunadamente, su respuesta no es amigable para los principiantes de Java. – user927387

+0

@ user927387 'java.util.function.Supplier' – erickson

10

Esto puede ser más pesado de lo que está buscando, sino que también va a 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> 
{ 
    T newObject(); 
} 

class MyClass<T> 
{ 
    T field; 
    public void myMethod(MyFactory<T> factory) 
    { 
     field = factory.newObject() 
    } 
} 
+1

Buen enfoque no reflectivo; la reflexión no siempre es una opción. myMethod debería poder aceptar MyFactory , ¿verdad? – erickson

+0

Buena llamada: querrá poner un comodín delimitado de fábrica para permitir que se creen objetos de tipo T y subclases de T en myMethod(). –

11

Otro enfoque no reflexivo es utilizar un patrón híbrido de generador/fábrica abstracta.

En Effective Java, Joshua Bloch Balón por encima del Builder en detalle, y aboga por una interfaz Constructor genérica:

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

constructores de hormigón pueden implementar esta interfaz, y fuera de las clases pueden utilizar el constructor de hormigón para configurar el Constructor según sea necesario. El constructor se puede pasar a MyClass como Builder<T>.

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.

1

Clase classOfT

 try { 
      t = classOfT.newInstance();//new T(); NOTE: type parameter T cannot be instantiated directly 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
Cuestiones relacionadas