在以下代码中:
public class Bar { ... }
public class Foo extends Bar { ... }
public class BarIterable implements Iterable<Bar> {
List<Foo> foos = ...
@Override
public Iterator<Bar> iterator() {
return foos.iterator(); // Error: Type mismatch ...
}
}
我在指定位置收到错误,因为foos.iterator()
返回Iterable<Foo>
而不是Iterable<Bar>
。不幸的是,简单的演员阵容不起作用:
return (Iterator<Bar>) foos.iterator(); // Error: Cannot cast ...
Java也不允许我将BarIterable
的定义更改为
public class BarIterable implements Iterable<? extends Bar> { ... // Error: A supertype may not specify any wildcard
解决这个问题的好方法是什么不涉及实现Iterable<Foo>
(Iterable-implementation来自另一个不了解Foo的接口)?
我是否必须自己编写一个“解包”每个值的包装器Iterator类?
答案 0 :(得分:6)
由于Foo
是Bar
的子类型,您只需投放List
。
return ((List<Bar>)(List<? extends Bar>) foos).iterator();
并禁止警告。
由Markus A编辑:
或者,您可以使用intermediate-cast-trick直接强制转换迭代器:
return (Iterator<Bar>)(Iterator<? extends Bar>) foos.iterator();
结束编辑
使用Java 8,您可以对元素进行流式处理,并构建List
类型的新Bar
。
@Override
public Iterator<Bar> iterator() {
return foos.stream().<Bar>map((foo) -> foo /* considered a Bar */).collect(Collectors.toList()).iterator();
}
但是你要做的很多中间操作只是为了从超类型的角度来看List
。