2009-08-24 4 views
5

me gustaría hacer una clase que se ve básicamente como esto:conseguir la clase de Java genérico, y la aplicación de interfaz de genéricos

public class MyClass<T implements Serializable) { 

    void function() { 
     Class c = T.class; 
    } 
} 

Dos errores:
- No puedo llamar T.class, aunque puedo hacer eso con cualquier otro tipo de objeto
- No puedo hacer cumplir que T implementa Serializable de esta manera

¿Cómo resuelvo mis dos problemas genéricos?

Saludos

Nik

+0

¿Podría agregar un ejemplo de lo que realmente quiere lograr? – Zed

Respuesta

7

No se puede obtener el tipo.

Los genéricos se implementan utilizando algo llamado 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 los parámetros de tipo y escriba los 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.

La esencia de esto es que la información de tipo es utilizada por el compilador y descartada, por lo que no está disponible en tiempo de ejecución.

En cuanto a la T implements Serializable hacer cumplir, sólo tiene la siguiente:

public class MyClass<T extends Serializable>) 
{ 
    public void function(T obj) 
    { 
    ... 
    } 
} 

Esta es una simple referencia a la una relación, por lo que una clase que implementa Serializable, es unaSerializable y puede pasar a function.

+1

Gracias por la gran explicación, ahora entiendo por qué no funciona, y he resuelto mi problema práctico con la solución propuesta por gjrwebber. ¡Gracias un montón! :-) – niklassaers

3

algo en este sentido debe hacerlo.

private Class<T> dataType; 
Type type = getClass().getGenericSuperclass(); 
if (type instanceof ParameterizedType) { 
    ParameterizedType paramType = (ParameterizedType) type; 
    dataType = (Class<T>) paramType.getActualTypeArguments()[0]; 
} else if (type instanceof Class) { 
    dataType = (Class<T>) type; 
} 
+0

Gracias por la solución, eso me ayudó a resolver el problema, y ​​las otras respuestas me ayudaron a comprender el problema. :-) ¡Ustedes son los mejores! :-) – niklassaers

+5

Obtuve sun.reflect.generics.reflectiveObjects.TypeVariableImpl no se puede convertir en java.lang.Class, ¿qué me falta? –

1

No se puede hacer T.class porque Java en realidad no sabe qué clase T es en tiempo de ejecución.

Toda esa información se pierde en la compilación.

Para obtener el objeto de clase para T se puede llamar getClass() en una instancia de T (si tiene acceso a uno) o requerir que el usuario pase el objeto de clase como un argumento a function, como:

void function(Class<T> c) 
+0

La sintaxis para el límite genérico de los argumentos es no

+0

Ah, a la derecha. Eliminé esa parte de mi respuesta. – sepp2k

+0

Gracias por los comentarios rápidos. (1) El problema con eso es que en mi función genérica quiero usar funciones que tomen T.class como un parámetro de entrada. Si no puedo hacerlo de esta manera, una solución no tan buena sería crear una instancia de un objeto de la clase T, pero tal como lo entiendo, tampoco puedo decir "nueva T()", nuevamente debido al borrado de tipo? (2) Doh, no vio el error tipográfico. Pero, mi compilador de Java afirma que espera una coma donde escribo implementos, eso es lo que quise decir con eso. EDITAR: Gracias tkopec, se extendió funcionó mucho mejor, no sabía que podía extender una interfaz – niklassaers

5

que hacer esto:

public class MyClass<T implements Serializable) { 

    void function(Class<T> tc) { 
     ... 
    } 
} 

Básicamente, usted tiene que pasar en la clase en tiempo de ejecución con el fin de verlo. También podría hacer algo como esto:

public class MyClass<T implements Serializable) { 
    Class<T> ct; 
    public MyClass(Class<T> ct){this.ct = ct;} 

    void function() { 
     ... //you know what the class is here 
    } 
} 

Es un poco molesto, pero no es realmente tan grande de un problema global.

+1

Muchas gracias, eso es una solución elegante :-) – niklassaers

+0

Esta es una solución muy simple y buena – satya

Cuestiones relacionadas