我有一个A类,一个B类延伸A
在另一个C类我有一个字段
private List<B> listB;
现在,由于一些不寻常的原因,我必须在C
中实现此方法public List<A> getList();
我尝试通过列表<A>
强制转换listB字段向列表<?>
的上传来实现此目的:
public List<A> getList(){
return (List<A>)(List<?>)listB;
}
客户应该
List<A> list = getList();
for(A a:list){
//do something with a
}
我做了一些测试,似乎工作正常,但说实话,我不确定所有可能的影响。
此解决方案是否正确?它是最好的解决方案吗?
感谢您的回答。
答案 0 :(得分:16)
不,这不安全。客户不应该能够
List<A> list = getList();
因为否则他们可以写
list.add(new C()); // Where C extends A
然后,当它尝试使用它时,知道列表为List<B>
的原始代码会出现问题,假设每个元素都与B
兼容。
您可以将原始列表包装为有效 - 或使getList
返回List<? extends A>
,这意味着客户端无论如何都无法向其添加项目。
答案 1 :(得分:3)
这样做的问题是,客户端可以在不知不觉中将A
个对象插入实际上只是更具体B
个对象的列表中:
c.getList().add(new A());
当您的代码尝试从列表中获取对象时,这会导致各种破坏,假设它是B
,但事实并非如此。
如果您的唯一目标是让客户端遍历列表,那么最好分发Iterable<A>
:
public Iterable<A> getAs() { return this.theListOfAs; }
通过这个Iterable
,人们只能检查和删除元素,但不能添加它们。
如果您也要禁用删除功能,请将List
的{{1}}包装在您自己的实现中,并在调用Iterable
时抛出UnsupportedOperationException
。