通过List <! - ? - > </superclass> </subclass>从List <subclass>转发到List <superclass>

时间:2010-07-07 13:14:25

标签: java generics collections wildcard

我有一个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
}

我做了一些测试,似乎工作正常,但说实话,我不确定所有可能的影响。

此解决方案是否正确?它是最好的解决方案吗?

感谢您的回答。

2 个答案:

答案 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