假设我有这段代码:
class ABC
{
List<Orange> list;
Orange orange;
public static Fruit getFirstOrange()
{
list = getFruits();
for(Fruit fruit:list) // Here is the confusion
{
if(fruit.name.equals("orange")
orange = (Orange) fruit;
break;
}
}
public List<Orange> getFruits()
{
return new List<orange>();
}
}
所以在每个循环的上面代码中,我应该在这种情况下使用Fruit或Orange类型。
for(Fruit fruit:list) // Here is the confusion
{
if(fruit.name.equals("orange")
orange = (Orange) fruit;
break;
}
*OR*
for(Orange fruit:list) // Here is the confusion
{
if(fruit.name.equals("orange")
orange = fruit;
break;
}
所以上面哪一个是正确的做法。我认为既然我的列表包含了橙色,我就不应该在每个循环中使用Fruit类型。
答案 0 :(得分:2)
鉴于
List<Orange> fruit;
然后for (Orange orange : fruit)
将循环遍历是橙色的每个水果,因为水果列表只能包含橙子。这是 迭代列表的最佳方式,因为它应用 最具体的类型来统一项目。
现在,考虑何时使用超类型
for (Fruit someFruit : fruit) // an Orange is also a Fruit, okay
someFruit.separateSlices(); // whoops! not all Fruit have slices
}
或
for (Object anyObject : fruit) // an Orange is also an Object, okay
anyObject.eat(); // whoops! can't eat random Objects
}
虽然可以使用强制转换,因为所有项目都保证为橙色,但它不会简单地在增强的for循环中改进类型。此外,在for循环中使用特定类型可以防止与某些类似的类型相关的错误。考虑一下,
List<Fruit> fruit; // now really fruit
for (Orange orange: fruit) { // error: incompatible types, won't compile
// as not all Fruit are Oranges
// ..
}
但是演员,
List<Fruit> fruit = new ArrayList<Fruit>();
fruit.add(new Orange());
fruit.add(new Apple()); // valid, an Apple is also a Fruit
for (Fruit someFruit: fruit) { // still most specific: Fruit, not Object
Orange orange = (Orange)someFruit; // runtime ClassCastException on Apple
}
因此,我的建议是使用适用于问题域的最具体/精炼类型。在原始问题的情况下,从一开始就将每个项目键入橙色;或者修改使用List<Orange>
存储各种不同水果的假设。
答案 1 :(得分:1)
如果list
是List<Orange>
,那么您当然应该使用for (Orange o : list)
,因为它是列表元素的类型。
如果list
是List<Fruit>
,那么您应该使用for (Fruit f : list)
。这样做的原因是列表能够容纳其他类型的元素,例如Apple
或Banana
(如果您实现了它们)。因此,您应该使用最近的超类,Fruit
。
答案 2 :(得分:1)
如果您的列表是橙色类型,那么您应该使用橙色。你的定义是
List<Orange> list;
所以你的循环可以是
for(Orange o : list) {}
如果您的列表是Fruit类型,那么您将在循环中使用Fruit,并在适当和必要时进行转换。