2010-11-12 6 views
16

En Java lors de la conversion d'un objet vers d'autres types, pourquoi la deuxième ligne génère-t-elle un avertissement relatif à la distribution, mais pas le premier?Java: conversion d'un objet en type générique

void a(Object o) { 
    Integer i = (Integer) o; 
    List<Integer> list = (List<Integer>) o; 
} 

/*Type safety: Unchecked cast from Object to List<Integer>*/ 
+0

La deuxième ligne génère un avertissement car seuls les génériques génèrent un tel avertissement. Le premier ne contient aucun générique, donc pas d'avertissement. –

Répondre

24

C'est parce que l'objet ne sera pas vraiment vérifier pour être un List<Integer> au moment de l'exécution en raison de d'effacement de type. Ce sera vraiment juste de le couler à List. Par exemple:

List<String> strings = new ArrayList<String>(); 
strings.add("x"); 
Object o = strings; 

// Warning, but will succeeed at execution time 
List<Integer> integers = (List<Integer>) o; 
Integer i = integers.get(0); // Bang! 

Voir Angelika Langer's Java Generics FAQ pour plus d'informations, en particulier les type erasure section.

5

La réponse de Jon est la bonne, mais parfois vous ne pouvez pas contourner cet avertissement (comme lorsque vous travaillez avec une API héritée). Dans ces cas, vous pouvez supprimer l'avertissement comme ceci:

@SuppressWarnings("unchecked") 
List<Integer> list = (List<Integer>) someApiThatReturnsNonGenericList(); 
6

Pour plus de clarté, laissez-moi un peu les exemples réécris ...

Je dirais que la différence cruxial entre:

void a(Object o) { 
    Integer i = (Integer) o; 
    ... 
} 

et

void a(Object o) { 
    List<Integer> list = (List<Integer>) o; 
    ... 
} 

est que, étant donné que il y a une erreur de type, le premier cast toujours immédiatement lancer une RuntimeException (spécifiquement, une ClassCastException) lorsqu'il est exécuté.

Alors que le second pourrait pas - tant que le paramètre d'entrée o est une sorte de List<?>, l'exécution sera juste de procéder, malgré d'une distribution incorrecte.

Si le code plus tard une exception ou non, dépend de ce que vous faites avec la liste.

Cependant, une exception peut être ne pas être levée à la ligne où la distribution a été faite, mais ailleurs (ce qui pourrait être un bogue difficile à tracer) ou pas du tout.

C'est ce que je comprends, c'est la raison pour laquelle les concepteurs-compilateurs ont considéré un avertissement approprié dans le second cas seulement.

+1

Excellente explication. – Trilarion

+0

Le premier * ne lancera pas toujours une exception CastClassException. L'objet entrant pourrait très bien être un 'Integer'. La première ligne peut lever une exception, tout comme la seconde si "o" n'est pas une "liste". –

+0

@Hot Licks: oui, c'est pourquoi j'ai écrit "étant donné qu'il y a une erreur de type" ci-dessus - j'ai même mis en gras;) – Rop

Questions connexes