2017-03-05 1 views
2

Considérons la spécification de la méthode put de l'interface java.util.Map.Pourquoi Map # put spécifie @throws ClassCastException?

Il dit:

@throws ClassCastException if the class of the specified key or value 
     prevents it from being stored in this map 

Map est une interface générique avec deux paramètres de type : K et V pour les objets clés et des objets de valeur respectivement. La signature de la méthode put est:

V put(K key, V value); 

Dans quelles conditions pourrait un appel à cette méthode provoquer une ClassCastException lors de l'exécution? Je pense que s'il y a un mélange de types génériques et bruts, alors en ignorant les avertissements du compilateur, cela peut arriver. Ainsi, après la relecture efficace Java 2, je modélise, après le unsafeAdd exemple (article n ° 23, pp 112.):

public class MapClassCastException { 
    public static void main(String[] args) { 
     Map<Integer, String> m = new HashMap<>(); 
     unsafePut(m); 
     System.out.println(m.get(1)); 
    } 

    private static void unsafePut(Map m) { // beware: Raw Type 
     m.put("blow", "up"); 
     m.put(new int[]{2, 4}, "xxx"); 
    } 
} 

Mais ce code ne pas échec à l'exécution avec ClassCastException, au lieu qu'il imprime null . (Bien sûr, j'ignore les avertissements du compilateur pour bien le comprendre). Quelqu'un peut-il montrer comment Map#put peut lancer un ClassCastException lors de l'exécution? (J'ai essayé ceci avec JDK 1.6, 1.7 et 1.8 et ils ont produit des résultats identiques).

+1

Essayez-le avec TreeMap. – chrylis

+0

Ah, cool. Merci @chrylis. J'ai oublié cette implémentation utile de "Map"! –

Répondre

1

Map est une interface qui définit essentiellement un contrat pour toutes les implémentations de cette interface. La documentation pour Map.put vous indique qu'il est possible que cette méthode lance un ClassCastException. Cela ne nécessite toutes les implémentations pour le jeter. Si vous regardez le documentation for HashMap.put, vous remarquerez qu'il ne mentionne pas ClassCastException du tout. Comme mentionné dans les commentaires, TreeMap.put jette un ClassCastException car il doit être en mesure de comparer avec précision les clés.

Si vous voulez implémenter votre propre java.util.Map, vous pourriez jeter ClassCastException si vous voulez restreindre le type d'une clé ou une valeur, même si les médicaments génériques sur l'interface ne peut pas appliquer que si vous arrive d'utiliser une Map brute type. Je pense que ce sont juste les implémenteurs de l'API Collections qui disent d'être prudents.