简体   繁体   English

使用Java泛型绑定类型参数

[英]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: 因此,从实现的角度来看,我有以下问题:

  1. Is using bounded type arguments a right approach? 使用有界类型参数是正确的方法吗?
  2. If Yes, What type of elements can it contain in the scenario explained above. 如果是,则在上述方案中它可以包含什么类型的元素。
  3. Can you throw in an example, where bounded type arguments are useful or the right scenario/way to implement them. 您能否举个例子说明有限类型实参很有用的情况,还是实现它们的正确方案/方式。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM