[英]Using Java Generics Bounded Type Arguments
我有一个Box
类,如下所示。
public class Box <E> {
private List<E> itmes = new ArrayList<>();
public void addItem(E e){
itmes.add(e);
}
public void addItemList(List<? extends E> itemList){
itmes.addAll(itemList);
}
public List<E> getItems(){
return itmes;
}
}
第一个实现使用无界类型参数,效果很好。 如下所示
Box<Apple> appleBox = new Box<>();
Apple fujiApple = new Apple("fujiApple");
Apple kashmiriApple = new Apple("kashmiriApple");
appleBox.addItem(fujiApple);
appleBox.addItem(kashmiriApple);
Box<Orange> orangeBox = new Box<>();
Orange weirdOrange = new Orange("weirdOrange");
Orange orangeOrange = new Orange("orangeOrange");
orangeBox.addItem(weirdOrange);
orangeBox.addItem(orangeOrange);
Box<Fruit> fruitBoxAll = new Box<>();
fruitBoxAll.addItemList(appleBox.getItems());
fruitBoxAll.addItemList(orangeBox.getItems());
但是现在,我想使用有界类型参数,如下所示
Box<? extends Fruit> fruitBox = new Box<>();
宣布? extends Fruit
? extends Fruit
为类型参数意味着Box
类中的List
也将是类型? extends Fruit
? extends Fruit
。 而以下代码将给出错误
fruitBox.addItem(fujiApple);
稍后,用户可能会尝试将橘子添加到同一列表中
fruitBox.addItem(orangeOrange);
这是不对的。 因此,我无法使用此有界类型参数对象来创建Fruit
子类型的Box
。 从Java的角度来看这是可以理解的,但是使用有界类型参数似乎没有用。
因此,从实现的角度来看,我有以下问题:
正如其他人指出的那样,PECS理念涵盖了您正在做的事情-生产扩展,超级消费者。 您应该真正阅读<? 超级T>和<? 在Java中扩展T>
List的问题在于,该列表被声明为某种类型,这是Fruit的特定子类,但是您试图将其视为Fruit的列表,但它不是类型安全的。
在哪里使用? extends Fruit
? extends Fruit
限制类型的? extends Fruit
是当您将列表返回给客户端时,客户端将a)仅尝试从列表中读取内容,b)仅关心列表中的对象实现了Fruit
接口。
例如
public void myMethod() {
List<? extends Fruit> myList = theListProducingMethod();
for (Fruit f: myList) {
f.fruitMethod();
}
}
public List<? extends Fruit> theListProducingMethod() {
final List<Orange> someList = new ArrayList<>();
someList.add(new Orange());
return someList;
}
这里要注意的是,返回的列表在myMethod
实际上是不可变的。 因为它的通用类型是<? extends Fruit>
<? extends Fruit>
无法以类型安全的方式在myMethod
中调用myList.add
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.