简体   繁体   中英

Java Lower Bound Wildcard

How come the List in the main method below compiles?

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
}

Seeing as bread is not a superclass of Drink? What is the rule that allows the compilation of the first and second lists but not the third? And if so then what are the main differences between

<?>  

and

<? super Drink>

Thanks!

The Java compiler uses type inference to determine the type parameter for calls to generic methods such as Arrays.asList . It determines the most specific type that can be derived as a supertype to all arguments.

For the first and second lists, there is an Object in the list, so Object is the inferred type parameter. That works for ? super Drink ? super Drink , because ? super Drink ? super Drink is a lower bound that Object satisfies. That also works for ? , the unbounded wildcard, because ? will match any inferred type parameter. These will compile as long as you have different names for these two list variables.

For the third list (called fourthList ?), you have a lower bound, ? extends Drink ? extends Drink , meaning that the type inferred must be a subtype of Drink , either Drink itself or a subclass. Because Breakfast is the inferred type, and Breakfast is not a subtype of Drink , this is a compiler error. If Bread were not in the list, then the inferred type would be Drink and this would compile.

extends is an upper bound - that means that any instance specified must be no "higher" in the inheritance hierarchy than the specified type.

From your example, ? extends Drink ? extends Drink is the upper bound - so every object must then extend from Drink to be legally assigned into that list.

super is a lower bound - that means that any instance specified must be no "lower" in the inheritance hierarchy than the specified type.

From your example, ? super Drink ? super Drink is the lower bound - so every object must then either be a type of Drink or a type of its ancestor - in this case, Object .

? is a wildcard - you actually don't care what type is in the collection if you're using it (since you can't get that information back). By default, that results in ? extends Object ? extends Object , and thus the upper bound rules apply (and are satisfied).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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