[英]Using Java Generics Bounded Type Arguments
I have a Box
class as shown below. 我有一个
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;
}
}
The first implementation uses unbounded type arguments, which works fine. 第一个实现使用无界类型参数,效果很好。 As shown below
如下所示
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());
But now, I want to use bounded type argument as shown below 但是现在,我想使用有界类型参数,如下所示
Box<? extends Fruit> fruitBox = new Box<>();
Declaring ? extends Fruit
宣布
? extends Fruit
? extends Fruit
as type argument means that List
inside Box
class will also be of type ? extends Fruit
? extends Fruit
为类型参数意味着Box
类中的List
也将是类型? extends Fruit
? extends Fruit
. ? extends Fruit
。 And following code will give an error 而以下代码将给出错误
fruitBox.addItem(fujiApple);
As at some point later, user may try to add oranges to the same list 稍后,用户可能会尝试将橘子添加到同一列表中
fruitBox.addItem(orangeOrange);
which is not right. 这是不对的。 So I cannot use this bounded type argument object to create a
Box
of sub-type of Fruit
. 因此,我无法使用此有界类型参数对象来创建
Fruit
子类型的Box
。 Which is understandable from Java point of view, but then using bounded type arguments seem not useful. 从Java的角度来看这是可以理解的,但是使用有界类型参数似乎没有用。
So from the implementation perspective, I have following questions: 因此,从实现的角度来看,我有以下问题:
As others have pointed out what you're doing is covered by the PECS idea - Produce Extends, Consumer Super. 正如其他人指出的那样,PECS理念涵盖了您正在做的事情-生产扩展,超级消费者。 You should really read Difference between <?
您应该真正阅读<? super T> and <?
超级T>和<? extends T> in Java
在Java中扩展T>
Your problem with List is that the list is declared as some type which is a specific subclass of Fruit but you're trying to treat it as a list of Fruit, which is not typesafe. List的问题在于,该列表被声明为某种类型,这是Fruit的特定子类,但是您试图将其视为Fruit的列表,但它不是类型安全的。
Where it's useful to use the ? extends Fruit
在哪里使用
? extends Fruit
? extends Fruit
bounded type is when you're returning a list to a client who will a) only ever try to read from the list and b) who only cares that objects in the list implement the Fruit
interface. ? extends Fruit
限制类型的? extends Fruit
是当您将列表返回给客户端时,客户端将a)仅尝试从列表中读取内容,b)仅关心列表中的对象实现了Fruit
接口。
eg 例如
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;
}
The thing to note here is that the returned list is effectively immutable in myMethod
. 这里要注意的是,返回的列表在
myMethod
实际上是不可变的。 Because its generic type is <? extends Fruit>
因为它的通用类型是
<? extends Fruit>
<? extends Fruit>
there's no way to call myList.add
in myMethod
in a type safe fashion. <? extends Fruit>
无法以类型安全的方式在myMethod
中调用myList.add
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.