2009-05-26 8 views
9

¿Hay alguna forma de almacenar el parámetro genérico pasado en la construcción en un parámetro? Mi objetivo:Clase de tienda genérica en campo en Java

class generic<T> { 
    Class<T> type; 
    public generic() { 
     super(); 
     this.type = //Something that gets class from T 
    } 
} 

Lo que estoy haciendo actualmente es la siguiente:

class generic<T> { 
    Class<T> type; 
    public generic(Class<T> type) { 
     super(); 
     this.type = type; 
    } 
} 

Parece tonto tener que especificar la clase dos veces, pero no estoy seguro de qué otra manera de hacerlo. Creo que esto podría ser posible con la reflexión, pero aún no lo he investigado. ¿Hay una manera más directa? Si no (como un lado) ¿por qué la pérdida de información?

+0

Si usa genéricos, ¿por qué quiere/necesita la clase? Esto tiene un olor extraño. – Instantsoup

+0

De acuerdo, no debería necesitar acceso al parámetro genérico en tiempo de ejecución ya que los genéricos son solo una característica de compilación ... –

Respuesta

10

Debido genéricos de Java se implementan con Type Erasure

Cuando se crea una instancia de un tipo genérico, el compilador traduce esos tipos por una técnica llamada Tipo de borrado - un proceso donde el compilador elimina toda información relacionada con escriba los parámetros y escriba argumentos dentro de una clase o método . La eliminación de tipos habilita las aplicaciones Java que usan genéricos a mantienen la compatibilidad binaria con Se crearon bibliotecas y aplicaciones Java que antes que los genéricos.

3

El tipo no se conserva en el tiempo de ejecución, por lo que no puede tomarlo como parámetro. Los genéricos en Java son estrictamente un concepto de tiempo de compilación (por razones de compatibilidad hacia atrás). Esto se llama Type Erasure.

Uno de los motivos por los que el objeto de clase toma un parámetro de tipo es precisamente solucionar este problema, por lo que puede tomar el objeto de clase para representar el tipo mediante programación.

8

Si utiliza un método de creación estático con inferencia de tipo en lugar del constructor, no será necesario especificar el tipo dos veces.

final class Generic<T> { 
    private final Class<T> type; 
    private Generic(Class<T> type) { 
     super(); 
     if (type == null) { 
      throw new NullPointerException(); 
     } 
     this.type = type; 
    } 
    public static <T> Generic<T> newInstance(Class<T> clazz) { 
     return new Generic<T>(clazz); 
    } 
} 
... 
    someFunction(Generic.newInstance(SomeType.class)); 

Por supuesto, si desea almacenar el resultado en una variable, ¡probablemente repita el tipo de todos modos!

Cuestiones relacionadas