2009-10-02 13 views
7

he el siguiente códigoUso de los genéricos hace que la advertencia de conversión sin control

String innerText = null; 
innerText = this.getException(detail.getChildElements()); 

haciendo esta advertencia

de seguridad Tipo: La expresión de tipo iterador necesita conversión sin marcar para conformar a iterador

El método al que se hace referencia es

private String getException(Iterator<OMElementImpl> iterator) { ... } 

El otro método, getChildElements(), está en un archivo JAR que no puedo tocar. No hay otras advertencias o errores.

De buscar en Google, parece que la forma habitual de deshacerse de este tipo de advertencia es

@SuppressWarnings("unchecked") 
String innerText = this.getException(detail.getChildElements()); 

porque el compilador no puede garantizar la seguridad antes de tiempo, pero preferiría evitar el uso de SuppressWarnings si es posible ... ¿hay una mejor manera?

EDIT: getChildElements() se documenta here

+5

Apenas esté satisfecho Los genéricos de Java permiten que su código compile en absoluto. Personalmente, dejaría allí la advertencia: es una advertencia perfectamente válida. –

Respuesta

16

Usted puede suprimir la advertencia, pero si lo hace, usted está confiando 100% en la biblioteca de terceros, y descartando la seguridad de Java tipos genéricos: que cualquier ClassCastException levantado en tiempo de ejecución ocurrirá justo en un lanzamiento explícito.

Nuestro estándar de codificación es suprimir las advertencias sólo cuando podemos probar el código es un tipo seguro — y tratar cualquier llamadas fuera del paquete como un cuadro negro, y no dependemos de cualquier comentario sobre el contenido de una colección en bruto Entonces, la supresión es extremadamente rara. Usualmente, si el código es de tipo seguro, el compilador puede determinarlo, aunque a veces tenemos que darle alguna ayuda. Las pocas excepciones involucran arreglos de tipo genérico que no "escapan" de un contexto privado.

Si no confía plenamente en la biblioteca de terceros, cree una nueva colección y agregue los contenidos después de enviarlos al OMEElementImpl. De esta forma, si hay un error en la biblioteca, lo descubriremos de inmediato, en lugar de tener un código muy distante en el tiempo y el espacio explotar con un ClassCastException.

Por ejemplo:

Iterator<?> tmp = detail.getChildElements(); 
Collection<OMElementImpl> elements = new ArrayList<OMElementImpl>(); 
while (tmp.hasNext()) 
    elements.add((OMElementImpl) tmp.next()); /* Any type errors found here! */ 
String innerText = getException(elements.iterator()); 

Recuerde que los genéricos no se inventaron para hacer que el código mirar bastante y requieren menos escribir! La promesa de los genéricos es la siguiente: Se garantiza que su código será seguro si se compila sin advertencias. Eso es todo. Cuando las advertencias son ignoradas o suprimidas, el código sin un operador de transmisión puede misteriosamente elevar un ClassCastException.


Actualización: En este caso, sobre todo, parece muy arriesgado suponer que el resultado de getChildElements es un iterador de OMElementImpl. En el mejor de los casos, puede suponer que son OMElement, y eso solo está implícito en la clase, no en el método en particular.

+0

Verificar los contenidos de una colección devuelta por una biblioteca de terceros como esta es un buen consejo. –

+0

Como alternativa a la creación de una nueva colección, consulte 'Iterables.transform' en Google Collections http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterables.html#transform (java.lang.Iterable,% 20com.google.common.base.Function) –

+0

Bueno, soy un nuevo desarrollador junior y me han asegurado que está bien suponerlo en este caso particular; Yo (y mi líder técnico, para el caso) simplemente odio ver el pequeño icono de advertencia. + 1/aceptado para dar buenos consejos generales, sin embargo. – Pops

Cuestiones relacionadas