从 List 向上转换列出<超类>通过列表>
我有一个类 A 和一个类 B 扩展 A
在另一个类 CI 有一个字段
private List<B> listB;
现在,由于某些不寻常的原因,我必须在 C 中实现此方法
public List<A> getList();
我尝试通过强制将 listB 字段向上转换为 List 来实现此目的
通过 List 转换:
public List<A> getList(){
return (List<A>)(List<?>)listB;
}
客户应该这样做
List<A> list = getList();
for(A a:list){
//do something with a
}
我做了一些测试,它似乎工作正常,但老实说,我不确定所有可能的影响。
这个解决方案正确吗?这是最好的解决方案吗?
感谢您的回答。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,这通常不是类型安全的。客户端不应该能够这样做,
因为否则他们可能会编写
Then将列表了解为
List
的原始代码,当它尝试这样做时将会出现问题使用它,假设每个元素都与B
兼容。您可以有效地包装原始列表以使其只读,或者使
getList
返回一个List
,这意味着客户端无论如何都无法向其中添加项目。如果您使用的列表实现是不可修改的,那么它实际上不会导致问题 - 但我个人仍然会尽可能避免它。
No, this isn't generally type-safe. The client shouldn't be able to do
because otherwise they could write
Then the original code which knows about the list as a
List<B>
will have problems when it tries to use it, assuming that every element is compatible withB
.You could either wrap the original list to make it read-only, effectively - or make
getList
return aList<? extends A>
, which means that clients won't be able to add items to it anyway.If the list implementation you're using is unmodifiable, then it won't actually cause problems - but I'd still personally avoid it where possible.
这样做的问题是,客户端可能会无意中将
A
对象插入到实际上只是更具体的B
对象的列表中:当您的code 尝试从列表中获取一个对象,假设它是
B
,但事实并非如此。如果您的唯一目标是让客户端迭代列表,那么最好提供一个
Iterable
:通过这个
Iterable
,人们只能检查和删除元素,但不添加它们。如果您还想禁用删除,请将
List
的Iterable
包装在您自己的实现中,在remove() 时抛出
被调用。UnsupportedOperationException
The problem with this is that clients can, unwittingly, insert
A
objects in what is actually a list of more specificB
objects only:This will cause all kinds of breakage when your code tries to take an object from the list assuming that it's a
B
, but it isn't.If your only goal is to let the client iterate over the list, it is better to hand out an
Iterable<A>
instead:Through this
Iterable
, one can only inspect and remove elements, but not add them.If you want to disable removal as well, wrap the
List
'sIterable
in your own implementation, throwingUnsupportedOperationException
whenremove()
is called.如果您想要可变性,
您也可以返回一个 new ArrayList(listB) 。
正如其他回复所提到的,向上转换集合是不安全的,因为调用者可能会通过将错误的元素放入其中来破坏它。幸运的是,类型系统阻止您这样做,您别无选择,只能使用这些类型良好的方法复制集合,因此它可以正常工作。
也适用于地图。
Simply do this
You could as well return a
new ArrayList(listB)
if you want mutability.As other responses mentioned, it is not safe for a collection to be upcast because a caller could corrupt it by putting wrong elements into it. Fortunately the type system prevents you from doing it and you have no choice but to copy the collection with these methods which are nicely typed so it just works.
Works for Maps too.