Java下界通配符

时间:2018-09-04 16:56:21

标签: java generics bounded-wildcard

下面的主要方法中的列表如何编译?

class Breakfast {

}

class Drink extends Breakfast {

}

class Juice extends Drink {

}

class Food extends Breakfast {

}

class Bread extends Food {

}

public static void main(String[] args) {

    Object object = new Object();
    Drink drink = new Drink();
    Juice juice = new Juice();
    Bread bread = new Bread();

    List<? super Drink> firstList = Arrays.asList(object, drink, juice, bread);

    List<?> secondList = Arrays.asList(object, drink, juice, bread);

    List<? extends Drink> thirdList = Arrays.asList(drink, juice, bread); //DOESN'T COMPILE
}

看到面包不是饮料的超类?允许编译第一和第二列表而不是第三列表的规则是什么?如果是这样,

之间的主要区别是什么
<?>  

<? super Drink>

谢谢!

2 个答案:

答案 0 :(得分:1)

Java编译器使用类型推断来确定用于调用诸如Arrays.asList之类的通用方法的类型参数。它确定可以作为所有参数的超类型派生的最特定类型。

对于第一和第二个列表,列表中有一个Object,因此Object是推断的类型参数。这适用于? super Drink,因为? super DrinkObject满足的下限。这也适用于?(无界通配符),因为?将匹配任何推断的类型参数。只要您为这两个列表变量使用不同的名称,它们就会编译。

对于第三个列表(称为fourthList?),您有一个下界? extends Drink,这意味着推断的类型必须是Drink的子类型,即{{1} }本身或子类。因为Drink是推断的类型,并且Breakfast不是Breakfast的子类型,所以这是编译器错误。如果Drink不在列表中,则推断的类型将为Bread并将编译。

答案 1 :(得分:0)

extends上限的边界-这意味着在继承层次结构中,指定的任何实例都不得比指定的类型“更高”。

在您的示例中,? extends Drink是上限-因此每个对象都必须从Drink延伸,才能合法地分配到该列表中。

super lower 的下界-意味着在继承层次结构中,指定的任何实例都不得比指定的类型“低”。

在您的示例中,? super Drink是下界-因此每个对象都必须是Drink的类型或其祖先的类型-在这种情况下为Object。 / p>

?是通配符-如果您使用的是集合,实际上您根本不会在意它们是什么类型(因为您无法获取该信息)。默认情况下,结果为? extends Object,因此上限规则适用(并得到满足)。