【发布时间】:2015-05-23 07:57:35
【问题描述】:
将List 的Banana 转换为List 的Fruit ...
public class Fruit { }
public class Banana extends Fruit { }
public List<Banana> allBananas() {
return new ArrayList<>(Arrays.asList(new Banana(), new Banana()));
}
...在返回之前我必须做以下两步铸造:
public List<Fruit> getFruits() {
List<? extends Fruit> fruits = (List<? extends Fruit>) allBananas();
return (List<Fruit>) fruits;
}
为了避免中间步骤,可以这样做:
public List<Fruit> getFruits() {
return allBananas().stream().collect(Collectors.toList());
}
但在这种情况下,我必须创建新的 List 对象,这在性能方面不太好。
我想我不明白某些事情,也许做错了。 我想知道我的代码是否完全正确且安全?如果是这样 - 有没有更好的投射方式?如果不是 - 有什么问题可以改进?
【问题讨论】:
-
无论如何,您在第一个版本中的演员阵容是不安全的。从根本上说,
List<Banana>不是List<Fruit>。我们不知道这里的上下文是什么 - 你应该实际上做的只是将签名更改为List<? extends Fruit>getFruit()` -
@ytterrr:我看不出这个答案与我的建议有什么关系......
-
但这里我建议
List<? extends Fruit>,所以它仍然相当具体。从根本上说,尽管您还没有告诉我们上下文。您想要现有列表的视图,还是现有列表的副本? -
对 - 如果有人在该列表中调用
view.add(new Apple()),您会期望发生什么?如果你提交了List<? extends Fruit>,他们就不能这样做,所以没关系 - 但如果你提交了List<Fruit>,那么他们可以,此时你要么破坏原来的List<Banana>,要么你必须检测它在执行时抛出一个异常......你还没有在你的问题中谈到你需要什么任何,这使得它无法回答。 -
嗯,这只是一个评论,因为它不能成为答案——因为问题不够清楚回答。如果您更新您的问题以使其可以回答,我可以添加答案...
标签: java generics inheritance polymorphism java-8