Sécurité du type : Distribution non vérifiée

Dans le fichier de contexte de mon application Spring, j'ai quelque chose comme:

<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>

Dans la classe java, l'implémentation ressemble à:

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

Dans Eclipse, je vois un avertissement qui dit:

Type safety : Unchecked cast from Object to HashMap<String,String>.

Qu'est-ce que j'ai fait de mal ? Comment puis-je résoudre ce problème ?

Solution

Tout d&#8217abord, vous gaspillez de la mémoire avec le nouvel appel à la création de HashMap. Votre deuxième ligne ignore complètement la référence à ce hashmap créé, le rendant ainsi disponible pour le garbage collector. Donc, ne faites pas ça, utilisez:

private Map someMap = (HashMap)getApplicationContext().getBean("someMap");

Deuxièmement, le compilateur se plaint que vous transformez l'objet en un HashMap sans vérifier si c'est bien un HashMap. Mais, même si vous faisiez:

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

Vous obtiendriez probablement toujours cet avertissement. Le problème est que getBean renvoie Object, donc on ne sait pas quel est le type. Le convertir directement en HashMap ne causerait pas le problème dans le second cas (et peut-être n'y aurait-il pas d'avertissement dans le premier cas, je ne sais pas à quel point le compilateur Java est pédant avec les avertissements pour Java 5). Cependant, vous le convertissez en un HashMap.

Les HashMaps sont en fait des cartes qui prennent un objet comme clé et ont un objet comme valeur, HashMap si vous voulez. Ainsi, il n'y a aucune garantie que lorsque vous obtenez votre haricot, il peut être représenté comme un HashMap car vous pourriez avoir HashMap car la représentation non-générique qui est retournée peut avoir n'importe quels objets.

Si le code se compile, et que vous pouvez exécuter String value = map.get("thisString&quot ;); sans aucune erreur, ne vous inquiétez pas de cet avertissement. Mais si la carte n'est pas entièrement composée de clés de chaînes de caractères et de valeurs de chaînes de caractères, vous obtiendrez une ClassCastException au moment de l'exécution, car les génériques ne peuvent pas empêcher que cela se produise dans ce cas.

Commentaires (1)

Un avertissement n'est que cela. Un avertissement. Parfois les avertissements ne sont pas pertinents, parfois ils ne le sont pas. Ils sont utilisés pour attirer votre attention sur quelque chose que le compilateur pense être un problème, mais qui ne l'est peut-être pas.

Dans le cas des casts, il va toujours donner un avertissement dans ce cas. Si vous êtes absolument certain qu'un cast particulier sera sûr, alors vous devriez envisager d'ajouter une annotation comme celle-ci (je ne suis pas sûr de la syntaxe) juste avant la ligne:

@SuppressWarnings (value="unchecked")
Commentaires (3)

Vous obtenez ce message parce que getBean renvoie une référence à un objet et que vous le convertissez en un type correct. Java 1.5 vous donne un avertissement. C&#8217est la nature de l&#8217utilisation de Java 1.5 ou d&#8217une version plus récente avec un code qui fonctionne comme celui-ci. Spring dispose d'une version sécurisée en termes de type

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

sur sa todo list.

Commentaires (0)