Esta es una versión simplificada del código en cuestión, una clase genérica usa otra clase con parámetros de tipo genérico y necesita pasar uno de los tipos genéricos a un método con parámetros varargs:
class Assembler<X, Y> {
void assemble(X container, Y... args) { ... }
}
class Component<T> {
void useAssembler(T something) {
Assembler<String, T> assembler = new Assembler<String, T>();
//generates warning:
// Type safety : A generic array of T is
// created for a varargs parameter
assembler.assemble("hello", something);
}
}
¿Hay alguna forma correcta de pasar el parámetro genérico a un método varargs sin encontrar esta advertencia?
Por supuesto algo como
assembler.assemble("hello", new T[] { something });
no funciona ya que no puede crear matrices genéricas.
Respuestas:
Aparte de agregar
@SuppressWarnings("unchecked")
, no lo creo.Este informe de error tiene más información, pero se reduce a que al compilador no le gustan las matrices de tipos genéricos.
fuente
Tom Hawtin señaló esto en un comentario, pero para ser más explícito: sí, puede resolver esto en el sitio de declaración (en lugar de los (potencialmente muchos) sitios de llamada): cambie a JDK7.
Como puede ver en la publicación del blog de Joseph Darcy , el ejercicio Project Coin para seleccionar algunas pequeñas mejoras incrementales del lenguaje para Java 7 aceptó la propuesta de Bob Lee de permitir que algo así como
@SuppressWarnings("varargs")
en el lado del método haga que esta advertencia desaparezca en situaciones donde se sabía que era seguro.Esto se ha implementado en OpenJDK con esta confirmación .
Esto puede o no ser útil para su proyecto (¡muchas personas no estarían felices de cambiar a una versión inestable de JVM previa al lanzamiento!) Pero tal vez lo sea, o tal vez alguien que encuentre esta pregunta más tarde (después de que JDK7 salga) ) lo encontrará útil.
fuente
Si buscas una interfaz de tipo fluido, puedes probar el patrón de construcción. No es tan conciso como varargs, pero es de tipo seguro.
Un método estático de tipo genérico puede eliminar parte de la placa repetitiva cuando se utiliza el constructor, al tiempo que conserva la seguridad de tipo.
El constructor
Usándolo
fuente
Collection
(en este caso, anArrayList
) es forzado sobre la persona que llama, mientras que pueden saber que aLinkedList
es más apropiado, o una matriz inmutable en sí misma (como los varargs de la pregunta OP). En un caso de uso no especializado, esto puede ser apropiado, pero solo señala que esto también es una limitación, en cierto modo, dependiendo del código que rodea esto y sus necesidades.La conversión explícita de parámetros a Object en la invocación del método vararg hará feliz al compilador sin recurrir a @SuppressWarnings.
Creo que el problema aquí es que el compilador necesita descubrir qué tipo concreto de matriz crear. Si el método no es genérico, el compilador puede usar información de tipo del método. Si el método es genérico, intenta averiguar el tipo de matriz en función de los parámetros utilizados en la invocación. Si los tipos de parámetros son homogéneos, esa tarea es fácil. Si varían, el compilador intenta ser demasiado inteligente en mi opinión y crea una matriz genérica de tipo unión. Entonces se siente obligado a advertirte al respecto. Una solución más simple hubiera sido crear Object [] cuando el tipo no se puede reducir mejor. La solución anterior obliga a eso.
Para entender esto mejor, juegue con invocaciones al método de lista anterior en comparación con el siguiente método de lista2.
fuente
Puede agregar @SafeVarargs al método desde Java 7, y no tiene que anotar en el código del cliente.
fuente
Puede haber sobrecargado los métodos. Esto no resuelve su problema, pero minimiza la cantidad de advertencias (y sí, ¡es un truco!)
fuente
Es un problema muy fácil de resolver:
List<T>
¡ Usar !Se deben evitar las matrices de tipo de referencia.
En la versión actual de Java (1.7), puede marcar el método con el
@SafeVargs
que eliminará la advertencia de la persona que llama. Sin embargo, tenga cuidado con eso, y aún estará mejor sin matrices heredadas.Consulte también las Advertencias y errores mejorados del compilador al usar parámetros formales no re-confiables con la nota técnica Métodos de Varargs .
fuente
Cuando se trabaja con matrices de tipo genérico, me veo obligado a pasar una referencia al tipo genérico. Con eso, puedo hacer el código genérico, usando java.lang.reflect.Array.
http://java.sun.com/javase/6/docs/api/java/lang/reflect/Array.html
fuente