Tipo de seguridad: lanzamiento sin control

Resuelto Saj asked hace 15 años • 10 respuestas

En el archivo de contexto de mi aplicación de primavera, tengo algo como:

<util:map id="someMap" map-class="java.util.HashMap" key-type="java.lang.String" value-type="java.lang.String">
    <entry key="some_key" value="some value" />
    <entry key="some_key_2" value="some value" />   
</util:map>

En la clase Java, la implementación se ve así:

private Map<String, String> someMap = new HashMap<String, String>();
someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");

En Eclipse, veo una advertencia que dice:

Seguridad de tipos: conversión sin marcar de Object a HashMap<String,String>

¿Qué salió mal?

Saj avatar Nov 04 '08 23:11 Saj
Aceptado

El problema es que una conversión es una verificación en tiempo de ejecución, pero debido al borrado de tipos, en tiempo de ejecución en realidad no hay diferencia entre a HashMap<String,String>y HashMap<Foo,Bar>para cualquier otro Fooy Bar.

Usa @SuppressWarnings("unchecked")y tapa tu nariz. Ah, y campaña a favor de genéricos cosificados en Java :)

Jon Skeet avatar Nov 04 '2008 17:11 Jon Skeet

Bueno, primero que nada, estás desperdiciando memoria con la HashMapllamada de nueva creación. Su segunda línea ignora por completo la referencia a este mapa hash creado, poniéndolo a disposición del recolector de basura. Entonces, no hagas eso, usa:

private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");

En segundo lugar, el compilador se queja de que usted envía el objeto a HashMapsin verificar si es un archivo HashMap. Pero, incluso si tuvieras que hacer:

if(getApplicationContext().getBean("someMap") instanceof HashMap) {
    private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
}

Probablemente aún recibirás esta advertencia. El problema es que getBeandevuelve Object, por lo que se desconoce cuál es el tipo. Convertirlo HashMapdirectamente no causaría el problema en el segundo caso (y tal vez no habría una advertencia en el primer caso, no estoy seguro de cuán pedante es el compilador de Java con las advertencias para Java 5). Sin embargo, lo está convirtiendo a HashMap<String, String>.

Los HashMaps son en realidad mapas que toman un objeto como clave y tienen un objeto como valor, HashMap<Object, Object>por así decirlo. Por lo tanto, no hay garantía de que cuando obtenga su bean pueda representarse como HashMap<String, String>porque podría haberlo hecho HashMap<Date, Calendar>porque la representación no genérica que se devuelve puede tener cualquier objeto.

Si el código se compila y puede ejecutarlo String value = map.get("thisString");sin errores, no se preocupe por esta advertencia. Pero si el mapa no es completamente de claves de cadena a valores de cadena, obtendrá un ClassCastExceptionen tiempo de ejecución, porque los genéricos no pueden impedir que esto suceda en este caso.

MetroidFan2002 avatar Nov 04 '2008 16:11 MetroidFan2002