2009-08-05 14 views
8

Si usted tiene un método con la firma:Java referencia de clase generized

Class<? extends List<String>> getObjectType() 
{ 
     return ?????; 
} 

¿Cómo devolver una versión genérica adecuada de la clase List?

return List.class; //errors 
return List<String>.class; //errors 
return List.class<String>; //errors 

¿cuál es la sintaxis adecuada para manejar esto?

Respuesta

9

Debe convertirlo explícitamente al tipo de devolución. Esto funciona:

return (Class<? extends List<String>>) List.class; 

Sí, simplemente se ve mal. Esta es solo una de las muchas razones por las que el sistema genérico de Java es un desastre.

+0

interesante, haciendo su sugerencia me se acerca, deja de Eclipse en las protestas. pero cuando voy a compilar la clase con el compilador de Java obtengo "tipos inconvertibles encontrados: java.lang.Class requerido: java.lang.Class > " –

+0

Es extraño, funciona para mí dentro de Eclipse, pero no cuando se compila en la línea de comandos. Nunca había visto eso antes. –

+0

Con la opción -nowarn funciona para el caso de devolver someList.getClass(), pero sigo recibiendo el mismo error que está viendo al intentarlo con List.class. –

2

Debe devolver la clase de algo que se extiende a List<String>. ArrayList<String> es un ejemplo. Usted puede tratar de:

ArrayList<String> myList = new ArrayList<String>(); 
... 
return (Class<? extends List<String>>)myList.getClass(); 
+1

Se requiere el lanzamiento explícito. El método getClass general devuelve el tipo clase . –

+0

@John: Gracias por señalar eso. Lo revisé, y ese es realmente el caso. Actualicé mi ejemplo para incluir el elenco. –

5

Del libro "Effective Java" (segunda edición, página 137): "No utilice los tipos de comodines como tipo de retorno En lugar de proporcionar una flexibilidad adicional para sus usuarios, que les obligaría a. usa tipos de comodines en su código de cliente ".

Dicho esto, para emitir, primero debe crear una variable temporal:

@SuppressWarnings("unchecked") 
Class<? extends List<String>> result = ....; 
return result; 

Esto funciona porque puede tener anotaciones en las tareas. No funciona en el return. También podría agregar eso al método, pero eso también escondería otros problemas.

+1

Para mí no solo advertí, sino que produjo un error de compilación hasta que agregué el molde. –

+0

Correcto. "Lista" y "Lista <...>" son tipos completamente diferentes (como String e Integer), por lo que necesita el elenco. Pero el yeso causará una advertencia y debes suprimir eso. –

0

List.class y List <String> .class - en todos estos casos necesita ser lanzado. Realmente necesita un tipo, que tiene Lista <cadena> en tiempo de ejecución, somethig así:

interface StringList extends List<String> {}; 

public Class<? extends List<String>> getObjectType() { 
    return StringList.class; 
} 
Cuestiones relacionadas