我调用了一个getElements
返回的方法Iterable<Element>
。
我这样做了:
List<Element> elements = (List<Element>) getElements();
这会产生错误:
java.lang.ClassCastException: com.utesy.Element$3
cannot be cast to java.util.List
我以为 aList
是一种Iterable
?
我调用了一个getElements
返回的方法Iterable<Element>
。
我这样做了:
List<Element> elements = (List<Element>) getElements();
这会产生错误:
java.lang.ClassCastException: com.utesy.Element$3
cannot be cast to java.util.List
我以为 aList
是一种Iterable
?
你可以把 Iterable 变成一个 List
List<Element> elements = Lists.newArrayList( getElements() );
是的,List<T>
extends Iterable<T>
,但这并不意味着您可以从任何 Iterable<T>
转换为List<T>
- 只有当值实际上是指一个类型的实例时List<T>
。完全有可能在Iterable<T>
不实现接口的其余部分的情况下实现List<T>
......在这种情况下,您希望会发生什么?
用更简单的术语来说,让我们更改Iterable<T>
为Object
和。extends ,因此您可以尝试将 from转换为... 但如果引用实际上引用 a (或为 null),则转换只会在执行时成功。List<T>
String
String
Object
Object
String
String
List<Element>
是 的一种Iterable<Element>
,但这并不意味着所有Iterable<Element>
对象都是List<Element>
对象。您可以将 a 转换List<Element>
为Iterable<Element>
,但反之则不行。
苹果是一种水果,但这并不意味着所有的水果都是苹果。你可以把苹果当作水果,但反过来不行。
为什么不:
Iterable<Element> i = ...; //is what you have
List<Element> myList = new LinkedList<Element>();
for (Element e:i) {
myList.add(e);
}
? 不需要谷歌库。
List 扩展了 Collection,后者又扩展了 Iterable。因此,您尝试强制转换为一个子类型,除非 getElements() 真的返回一个 List (签名不以任何方式保证),否则该子类型将不起作用。
请参阅:http: //download.oracle.com/javase/1.5.0/docs/api/java/util/List.html
List
是意义的子接口,Iterable
List 几乎包含了 Iterable 所拥有的所有东西,但反之则不然。因此,并非 List 实例中的所有方法在 Iterable 中都具有等价物。
尽量避免这种类型的铸造。
我建议您快速浏览一下Java 6 API和有关强制转换的教程
并非所有Iterable
s 都是s,因此将任意值强制转换为 a 是List
不安全的。Iterable
List
以 anySet
为例,aHashSet
是Iterable
但元素没有顺序,所以它不能实现List
接口,因此不是 a List
。
从异常消息中可以清楚地看出,
Iterable<Element>
它不能转换为 List<Element>
所以你需要List<Element>
从getElements()
List 实现了 Iterable 接口,但这并不意味着 Iterable 可以被强制转换回 List。Iterable 更为通用,可能是 Hash 或某种与 List 无关的奇异类型。(看起来 getElements() 返回某个匿名内部类的实例,该类包含在其类中的 getElements 旁边)。
如果 getElements 碰巧包含列表,那么这将是一个有效的强制转换。由于 getElements() 返回的类型实际上不是 List 这会产生运行时错误。
您可以尝试使用以下方式设置警卫instanceof
:
if (AnElement instanceof AList){
//cast
AList = (AnList)Element
}