Pregunta

En mi primavera en el contexto de aplicación de archivo, tengo algo así 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 una clase java, la aplicación se ve como:

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

En Eclipse, veo una advertencia que dice:

Tipo de seguridad:Desactivada elenco de Objeto HashMap

¿Qué hice mal?¿Cómo puedo resolver el problema?

¿Fue útil?

Solución

Bueno, antes que nada, estás desperdiciando memoria con la nueva HashMap llamada de creación. Su segunda línea ignora por completo la referencia a este hashmap creado, por lo que está disponible para el 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 convierte el objeto en un getBean sin verificar si es un Object. Pero, incluso si tuviera que hacer:

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

Probablemente aún reciba esta advertencia. El problema es que HashMap<String, String> devuelve HashMap<Object, Object>, por lo que se desconoce cuál es el tipo. Convertirlo a HashMap<Date, Calendar> directamente no causaría el problema con el segundo caso (y quizás no habría una advertencia en el primer caso, no estoy seguro de cuán pedante es el compilador de Java con advertencias para Java 5). Sin embargo, lo está convirtiendo en un String value = map.get("thisString");.

HashMaps son realmente mapas que toman un objeto como clave y tienen un objeto como valor, ClassCastException si lo desea. Por lo tanto, no hay garantía de que cuando obtenga su bean pueda representarse como un <=> porque podría tener <=> porque la representación no genérica que se devuelve puede tener algún objeto.

Si el código se compila y puede ejecutar <=> sin ningún error, no se preocupe por esta advertencia. Pero si el mapa no es completamente de claves de cadena a valores de cadena, obtendrá un <=> en tiempo de ejecución, porque los genéricos no pueden impedir que esto suceda en este caso.

Otros consejos

El problema es que un cast es una comprobación en tiempo de ejecución -, pero debido al tipo de borrado, en tiempo de ejecución no hay realmente ninguna diferencia entre un HashMap<String,String> y HashMap<Foo,Bar> para cualquier otro Foo y Bar.

Uso @SuppressWarnings("unchecked") y mantener la nariz.Ah, y la campaña para la reificación de los genéricos en Java :)

Como los mensajes anteriores indican que la Lista no se pueden diferenciar entre un List<Object> y un List<String> o List<Integer>.

He resuelto este mensaje de error para un problema similar:

List<String> strList = (List<String>) someFunction();
String s = strList.get(0);

con la siguiente:

List<?> strList = (List<?>) someFunction();
String s = (String) strList.get(0);

Explicación:El primer tipo de conversión se comprueba que el objeto es una Lista sin preocuparse acerca de los tipos a cabo dentro (ya que no podemos comprobar la interna de los tipos en el nivel de Lista).La segunda conversión es ahora necesario porque el compilador sólo conoce la Lista contiene algún tipo de objetos.De esta forma se comprueba el tipo de cada objeto en la Lista como la que se accede.

Una advertencia es solo eso. Una advertencia. Algunas veces las advertencias son irrelevantes, otras no. Están acostumbrados a llamar su atención sobre algo que el compilador cree que podría ser un problema, pero puede no serlo.

En el caso de los yesos, siempre dará una advertencia en este caso. Si está absolutamente seguro de que un reparto en particular será seguro, entonces debería considerar agregar una anotación como esta (no estoy seguro de la sintaxis) justo antes de la línea:

@SuppressWarnings (value="unchecked")

Recibe este mensaje porque getBean devuelve una referencia de Objeto y la está convirtiendo en el tipo correcto. Java 1.5 te da una advertencia. Esa es la naturaleza del uso de Java 1.5 o superior con código que funciona así. Spring tiene la versión typesafe

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

en su lista de tareas pendientes.

Si realmente quiere deshacerse de las advertencias, una cosa que puede hacer es crear una clase que se extienda desde la clase genérica.

Por ejemplo, si está intentando usar

private Map<String, String> someMap = new HashMap<String, String>();

Puede crear una nueva clase como tal

public class StringMap extends HashMap<String, String>()
{
    // Override constructors
}

Luego, cuando usas

someMap = (StringMap) getApplicationContext().getBean("someMap");

El compilador SÍ sabe cuáles son los tipos (ya no genéricos), y no habrá advertencia. Puede que esta no siempre sea la solución perfecta, algunos podrían argumentar que este tipo de derrotas el propósito de las clases genéricas, pero todavía está reutilizando todo el mismo código de la clase genérica, solo está declarando en el momento de la compilación qué tipo quieres usar.

Otra solución, si te encuentras lanzando mucho el mismo objeto y no quieres ensuciar tu código con @SupressWarnings("unchecked"), sería crear un método con la anotación. De esta manera, está centralizando el reparto y, con suerte, reduciendo la posibilidad de error.

@SuppressWarnings("unchecked")
public static List<String> getFooStrings(Map<String, List<String>> ctx) {
    return (List<String>) ctx.get("foos");
}

El código a continuación causa advertencia de seguridad de tipo

Map<String, Object> myInput = (Map<String, Object>) myRequest.get();

  

Workorkund

Cree un nuevo objeto de mapa sin mencionar los parámetros porque el tipo de objeto contenido en la lista no está verificado.

Paso 1: Crear un nuevo mapa temporal

Map<?, ?> tempMap = (Map<?, ?>) myRequest.get();

Paso 2: Crear una instancia del mapa principal

Map<String, Object> myInput=new HashMap<>(myInputObj.size());

Paso 3: itera el mapa temporal y establece los valores en el mapa principal

 for(Map.Entry<?, ?> entry :myInputObj.entrySet()){
        myInput.put((String)entry.getKey(),entry.getValue()); 
    }

La solución para evitar la advertencia no verificada:

class MyMap extends HashMap<String, String> {};
someMap = (MyMap)getApplicationContext().getBean("someMap");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top