Esto surgió como una pregunta que hice en una entrevista recientemente como algo que el candidato deseaba ver agregado al lenguaje Java. Es comúnmente identificado como un dolor que Java no tenga genéricos cosificados, pero, cuando se le presiona, el candidato no pudo decirme el tipo de cosas que podría haber logrado si estuvieran allí.
Obviamente, debido a que los tipos sin procesar están permitidos en Java (y las comprobaciones inseguras), es posible subvertir los genéricos y terminar con un que (por ejemplo) realmente contiene s. Esto claramente podría hacerse imposible si se reificara la información de tipo; ¡pero debe haber más que esto!List<Integer>
String
¿Podrían las personas publicar ejemplos de cosas que realmente querrían hacer, si estuvieran disponibles genéricos cosificados? Quiero decir, obviamente podrías obtener el tipo de a en tiempo de ejecución, pero ¿qué harías con él?List
public <T> void foo(List<T> l) {
if (l.getGenericType() == Integer.class) {
//yeah baby! err, what now?
EDIT: Una actualización rápida de esto, ya que las respuestas parecen estar principalmente preocupadas por la necesidad de pasar un como parámetro (por ejemplo). Estaba buscando más algo en la línea de donde esto simplemente no es posible. Por ejemplo:Class
EnumSet.noneOf(TimeUnit.class)
List<?> l1 = api.gimmeAList();
List<?> l2 = api.gimmeAnotherList();
if (l1.getGenericType().isAssignableFrom(l2.getGenericType())) {
l1.addAll(l2); //why on earth would I be doing this anyway?
Solución
Lo que más comúnmente me muerde es la incapacidad de aprovechar el envío múltiple a través de múltiples tipos genéricos. Lo siguiente no es posible y hay muchos casos en los que sería la mejor solución:
public void my_method(List<String> input) { ... }
public void my_method(List<Integer> input) { ... }
Otras respuestas
Me viene a la mente la seguridad del tipo. La reducción a un tipo parametrizado siempre será insegura sin genéricos reificados:
List<String> myFriends = new ArrayList();
myFriends.add("Alice");
getSession().put("friends", myFriends);
// later, elsewhere
List<Friend> myFriends = (List<Friend>) getSession().get("friends");
myFriends.add(new Friend("Bob")); // works like a charm!
// and so...
List<String> myFriends = (List<String>) getSession().get("friends");
for (String friend : myFriends) print(friend); // ClassCastException, wtf!?
Además, las abstracciones filtrarían menos, al menos las que pueden estar interesadas en la información de tiempo de ejecución sobre sus parámetros de tipo. Hoy en día, si necesita algún tipo de información de tiempo de ejecución sobre el tipo de uno de los parámetros genéricos, también debe pasarla. De esa manera, su interfaz externa depende de su implementación (ya sea que use RTTI sobre sus parámetros o no).Class