« Iterable <élément> ne peut pas être coulé à la liste <élément> » - est-ce pas `list` un type de` Iterable`?
-
08-10-2019 - |
Question
J'appelle une méthode getElements
qui retourne Iterable<Element>
.
Je l'ai fait:
List<Element> elements = (List<Element>) getElements();
Cela génère l'erreur:
java.lang.ClassCastException: com.utesy.Element$3
cannot be cast to java.util.List
Je pensais qu'un List
était un type de Iterable
?
La solution
Oui, List<T>
étend Iterable<T>
, mais cela ne signifie pas que vous pouvez lancer à partir de any Iterable<T>
à List<T>
- uniquement lorsque la valeur en fait fait référence à une instance d'un de type de List<T>
. Il est tout à fait possible de mettre en œuvre Iterable<T>
sans mettre en oeuvre le reste de l'interface List<T>
... dans ce cas, qu'est-ce que vous vous attendez à arriver?
Pour le dire en termes plus simples, Changeons Iterable<T>
à Object
et List<T>
à String
. String
étend Object
, de sorte que vous pouvez essayer de fonte Object
à String
... mais le CAST ne réussira au moment de l'exécution si la référence en fait fait référence à un String
(ou est nulle).
Autres conseils
Vous pouvez activer Iterable dans une liste avec
List<Element> elements = Lists.newArrayList( getElements() );
List<Element>
est un type de Iterable<Element>
, mais cela ne signifie pas que tous les objets sont des objets Iterable<Element>
List<Element>
. Vous pouvez jeter un List<Element>
comme Iterable<Element>
, mais pas l'inverse.
Une pomme est un type de fruit, mais cela ne signifie pas que tous les fruits sont les pommes. Vous pouvez lancer une pomme comme un fruit, mais pas l'inverse.
pourquoi pas:
Iterable<Element> i = ...; //is what you have
List<Element> myList = new LinkedList<Element>();
for (Element e:i) {
myList.add(e);
}
? pas besoin lib google.
Liste étend la collection qui à son tour s'étend Iterable. Par conséquent, vous essayez de caster un sous-type qui ne fonctionnera pas à moins getElements () est vraiment de retour d'une liste (que la signature ne garantit en aucune façon).
Voir: http: // téléchargement. oracle.com/javase/1.5.0/docs/api/java/util/List.html
List
est subinterface de sens Iterable
cette liste comprend à peu près tout ce qui a Iterable, mais pas l'inverse. Donc, toutes les méthodes dans une instance de liste aurait un équivalent en Iterable.
Essayez d'éviter ce genre de coulée.
Je vous recommande de jeter un coup d'œil sur la page Java 6 API et les tutoriels couvrant casting
De message d'exception, il est clair que
Iterable<Element>
ne peut être converti List<Element>
vous devez retourner List<Element>
de getElements()
Liste implémente l'interface Iterable, mais cela ne signifie pas Iterable peut être rejetterait à la liste. Iterable est beaucoup plus général et peut-être Hash ou un certain type exotique qui n'a aucun rapport à la liste. (Il ressemble à getElements () retourne une instance d'une classe interne anonyme contenue aux côtés getElements dans sa classe).
Si getElements se passerait-il contenir des listes alors ce serait un casting valide. Comme le type retourné par getElements () n'a pas fait une liste ce produit une erreur d'exécution.
ne sont pas tous Iterable
s sont List
s, donc ce n'est pas sûr de jeter un coup Iterable
arbitraire à un List
.
Prenez une Set
par exemple , un HashSet
est Iterable
mais les éléments n'a pas d'ordre, donc il ne peut pas implémenter l'interface List
, et est donc pas un List
.
vous pouvez essayer de placer un garde instanceof
:
if (AnElement instanceof AList){
//cast
AList = (AnList)Element
}