简体   繁体   中英

Lower bound wildcards

I am trying understand the following code snippet, searched links on stackoverflow with regards to lowerbound and upperbound

Just trying to get over the confusion in the following line ,

si=s//OK why? arrays of objects can be implicitly casted to arrays of integers?

 List<? extends Number> l = new ArrayList<>();
 List<? extends Integer> i = new  ArrayList<>();
 l = i;//OK i is a subtype of l

 List<? super Number> s = new ArrayList<>();
 List<? super Integer> si = new  ArrayList<>();

 si = new ArrayList<Integer>();//OK understand integer matches the pattern of ? super Integer
 s = new ArrayList<Object>();//OK understand that object is superclass of Number

 si=s//OK why?  arrays of objects can be implicitly casted to arrays of integers?

 //consider this
 List<Integer> integers = new ArrayList<Integer>();
 List<Object> objects = new ArrayList<Object>();
 integers = objects; //NOT OK Type mismatch: cannot convert from List<Object> to List<Integer>

 //consider this
 Integer ten = 10; //integer ten
 Object none = new Object();//some none
 ten = none;//NOT OK  none cannot be implicitly casted to ten  

Any help is appreciated

Remember that gnerics are for the benefit of the compiler not runtime information.

When you do si = s you are assigning a List of something that is a superclass of Number to a variable that can reference a List of something that is a superclass of Integer.

If it was a list of Number it would still be a list of Something that is a superclass of Integer.

We know it is actually an Arraylist of Object because you have assigned so previously.

We also know that ArrayList of Object extends List of Object.

List of Object is a List of something that is a superclass of Number which is why the previous assignment worked.

We also know that List of Object is a list of something that is a superclass of Integer but that is irrelevant to the compiler it only cares that any superclass of Number is also a superclass of Integer.

I wonder if you're clear on why you would use <? super Number> <? super Number> instead of <? extends Number> <? extends Number> ...

Declaring a type with <? extends Number> <? extends Number> guarantees to anything that takes that type that it will at least honour the contract of a Number . But a piece of code given a list of such type cannot add new members to the list. Consider this code:

void appendInteger (List <? extends Number> list) {
   list.add (new Integer (3)); // Compiler error on this line
}

You could call this with appendInteger (new ArrayList <Double> ()); Now, both Double and Integer extend Number , so the parameter will be accepted by the compiled. But you can see that if the append is allowed then the contract of the declaration in the calling code will be violated. For that reason the compiler will not allow any code that adds or replaces members in any structure declared with <? extends T> <? extends T> . The above method will cause a compiler error.

In brief, with upper-bounded wild-card types you can read the items but not place members into the structure.

Conversely, using List <? super Number> List <? super Number> means that the objects in the list are not more specific than Number . Consider this method:

void getInteger (java.util.List <? extends Number> list) {
    Number n = list.get (0); // Compiler error on this line
}

The code has no idea what the type is of the elements in list . So the compiler will vomit with the method too. You can add or replace members in list with objects of any type that is in the inheritance path of Number . But to read the members of the list you have to treat them as type Object or use a type cast:

Object v = list.get (0);  // this will work
Number n = (Number) list.get (0);  // this will also work

Given this knowledge, look again at the objects involved in si = s . Remember that you cannot read items from these structures, only add or replace members. Any object that you can place in s will also be acceptable in si . So therefore it is acceptable to assign s to si .

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