Domanda

ho chiamato un metodo che restituisce getElements Iterable<Element>.

Ho fatto questo:

List<Element> elements = (List<Element>) getElements();

Questo genera l'errore:

java.lang.ClassCastException: com.utesy.Element$3 
cannot be cast to java.util.List

Ho pensato che una List era un tipo di Iterable?

È stato utile?

Soluzione

Sì, List<T> estende Iterable<T>, ma questo non significa che si può lanciare da qualsiasi Iterable<T> a List<T> - solo quando il valore effettivamente si riferisce a un'istanza di un tipo di List<T>. E 'del tutto possibile implementare Iterable<T> senza implementare il resto dell'interfaccia List<T> ... in questo caso, ci si può aspettare che accada?

Per dirla in termini più semplici, cambiamo Iterable<T> per Object e List<T> a String. String estende Object, in modo da poter cercare per cast Object a String ... ma il cast avrà successo solo in fase di esecuzione se il riferimento effettivamente si riferisce a un String (o è nullo).

Altri suggerimenti

È possibile attivare Iterable in un elenco con

List<Element> elements = Lists.newArrayList( getElements() );

List<Element> è un tipo di Iterable<Element>, ma questo non significa che tutti gli oggetti sono oggetti Iterable<Element> List<Element>. È possibile lanciare un List<Element> come Iterable<Element>, ma non viceversa.

Una mela è un tipo di frutta, ma questo non significa che tutti i frutti sono le mele. Si può lanciare una mela come un frutto, ma non viceversa.

Perché non:

    Iterable<Element> i = ...; //is what you have
    List<Element> myList = new LinkedList<Element>();
    for (Element e:i) {
        myList.add(e);
    }

? non ha bisogno di google lib.

Lista estende Collection che a sua volta si estende Iterable. È quindi cercando di fusione a un sottotipo che non funziona a meno che getElements () in realtà restituisce un elenco (che la firma non fa in alcun modo garantire).

See: http: // download. oracle.com/javase/1.5.0/docs/api/java/util/List.html

List è un subinterface di Iterable significato Tale elenco comprende praticamente tutto quello che Iterable ha, tuttavia, non il contrario. Quindi non tutti i metodi in un'istanza List avrebbero un equivalente in Iterable.

Cercate di evitare questo tipo di casting.

I raccomanderebbe di dare un'occhiata veloce al Java 6 API e i tutorial che coprono fusione

Da messaggio di eccezione è chiaro che Iterable<Element> non è calcinabile a List<Element>

Quindi è necessario tornare List<Element> da getElements()

Elenco implementa l'interfaccia Iterable, ma questo non significa Iterable possono essere lanciati indietro alla lista. Iterable è molto più generale e può essere Hash o qualche tipo esotico che non ha alcuna relazione alla Lista. (Sembra getElements () restituisce un'istanza di una classe interna anonima contenuta fianco getElements nella sua categoria).

Se getElements non sarebbe accaduto a contenere liste allora questo sarebbe un cast valido. Come il tipo restituito da getElements () non era in realtà un elenco questo produce un errore di run-time.

Non tutti i Iterables sono Lists, quindi non è sicuro di lanciare un Iterable arbitrario ad un List.

Prendere qualsiasi Set ad esempio , un HashSet è Iterable ma gli elementi senza fine, quindi non può implementare l'interfaccia List, e non è quindi un List.

si può provare a mettere una guardia con instanceof:

if (AnElement instanceof AList){
    //cast
    AList = (AnList)Element
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top