繁体   English   中英

使用Java泛型绑定类型参数

[英]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的角度来看这是可以理解的,但是使用有界类型参数似乎没有用。

因此,从实现的角度来看,我有以下问题:

  1. 使用有界类型参数是正确的方法吗?
  2. 如果是,则在上述方案中它可以包含什么类型的元素。
  3. 您能否举个例子说明有限类型实参很有用的情况,还是实现它们的正确方案/方式。

正如其他人指出的那样,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.

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