reverseorder collection java generics reflection

java - collection - Cómo obtener la Clase<T> de la Lista<T>



hashset c# (2)

Me siento completamente tonto por tener que preguntar esto, pero no logro entender por qué no se compila el siguiente código Java:

void <T> doSomething(List<T> items) { Class<? extends T> clazz = items.get(0).getClass(); ... }

Desde el documento de Java:

El tipo de resultado real es Clase <? se extiende | X |> donde | X | es el borrado del tipo estático de la expresión en la que se llama a getClass. Por ejemplo, no se requiere conversión en este fragmento de código:

Número n = 0; Clase <? extiende el número> c = n.getClass ();

EDITAR:

  1. Encontré esta bonita explicación de lo que significa la eliminación del tipo estático .

  2. Hay una manera de preservar la información de tipo genérico usando subclases, conocida como token de supertipo . Una respuesta ahora eliminada de manera útil señaló que la biblioteca de Guayaba tiene una utilidad conveniente para explotar esto.

  3. Aquí hay un gran artículo sobre GenTyRef extraer tipos genéricos de manera reflexiva y una buena lib, llamada GenTyRef , que lo simplifica

  4. Bifurcé GenTyRef para agregar soporte para trabajar con AnnotatedType s (introducido en Java 8). Se llama GenAnTyRef (y está en Maven Central)


El borrado del tipo estático de items.get(0) es Object (ya que T se borra durante la compilación).

Por items.get(0).getClass() tanto, items.get(0).getClass() devuelve una Class<? extends Object> Class<? extends Object> , no una Class<? extends T> Class<? extends T> , lo que explica por qué su intento de asignación falla.

Esto pasará la compilación:

Class<? extends Object> clazz = items.get(0).getClass();

Si desea que la Class del parámetro genérico sea conocida por ese método, puede pasarla como un argumento adicional.

void doSomething(List<T> items, Class<T> clazz) { }


En primer lugar, debe definir T como parámetro de tipo para el método: <T> void doSomething . ¿Entonces necesitas un elenco para la Class<? extends T> Class<? extends T> . Así es como puedes juntar:

<T> void doSomething(List<T> items) { Class<? extends T> clazz = (Class<? extends T>) items.get(0).getClass(); ... }