This article talks about Java Generic Declaration <. Extends e> and <. The role and difference of Super e> <. Extends E>
? The extends e> is the Upper Bound (upper bound) wildcard that restricts the upper bounds of the type of the element, such as
list<? extends fruit> fruits;
Indicates that the upper bound of the element type in the collection is a fruit type, that is, only a subclass of fruit or fruit, so it is reasonable for the following assignment
Fruits = new arraylist<fruit> ();
Fruits = new arraylist<apple> ();
If the parent class with the element type fruit in the collection is compiled with an error, such as
Fruits = new arraylist<object> ()//compile does not pass
With the above basis, and then look at it. Extends e> read-write operation of a qualified set
1, write
Because the element type contained in the collection fruits is fruit or fruit subclasses, it is intuitive to tell us that it is possible to add a fruit type object or its subclass object to fruits
Fruits.add (New Fruit ());//compilation does not pass
Fruits.add (new Apple ());/compile does not pass
The result is that the compilation does not pass, why. Because.? The extends fruit> simply tells the compiler the type upper bound of the element in the collection, but it is specific to what type of compiler is not known, fruits can point to arraylist<fruit>, or point to Arraylist<apple >, arraylist<banana>, which means that its type is indeterminate, and since it is indeterminate, the compiler can only block the addition of elements for type safety. For example, when you add an apple, but fruits points to arraylist<banana> at this point, obviously the type is incompatible. Except, of course, NULL, because it can represent any type.
2, Read
Regardless of what the fruits points to, the compiler can determine that the element being fetched is a fruit type, and that all elements in the Read collection are allowed
Fruit Fruit = fruits.get (0);//Compile Through
add:<?> yes. Extends Object> <. Super E>
? The Super E> is a wildcard character for the Lower Bound (lower bound) that restricts the lower type of the element, such as
list<? Super apple> apples;
Indicates that the lower bound of the element type in the collection is the Apple type, that is, only Apple or Apple's parent class, so the following assignment is reasonable
Apples = new arraylist<apple> ();
Apples = new arraylist<fruit> ();
Apples = new arraylist<object> ();
If the element type is a subclass of Apple, the compilation is different
Apples = new arraylist<redapple> ()//compile does not pass
Look at the same thing. The read-write operation of a super e> qualified set
1, write
Since the element in apples is a parent of Apple or Apple, we cannot determine which specific type it is, but it is certain that the apple and Apple subclasses are compatible with this "indeterminate class" because it is definitely a subclass of this "indeterminate type", That means we can add an Apple or Apple subclass object to the collection, so the following additions are allowed
Apples.add (New Apple ());
Apples.add (New Redapple ());
It cannot add any parent object of the fruit, for example, when you add a fruit type object to the apples, but at this point the apples points to arraylist<apple> Obviously the type is incompatible, fruit is not a subclass of Apple
Apples.add (New Fruit ());//compilation does not pass
2, Read
The compiler allows the element to be fetched from the apples, but cannot determine what type of acquired element it is, but only the subclass of the object type, so we want to get the elements of the corresponding type that are stored in to be forced type conversions only
Apple Apple = (apple) apples.get (0);//Get element is type Object
The problem is that JDK1.5 introduced generics to avoid the tedious operation of coercion type conversions, then use generics. What's super e> doing? Here we have to talk about the universal pecs law.
pecs Law pecs: Producer (Producer) uses extends, consumer (Consumer) uses Super
1, producer If you need a collection that provides an element of type E, use the generic wildcard character. Extends E>. It is like a producer who can provide data. 2. Consumer If you need a collection that can only load type E elements, use the generic wildcard character. Super e>. It's like a consumer that can consume the data you provide. 3, both producers and consumers Both store and read, then do not use generic wildcard characters. Pecs Example Example of the JDK collection operations help class collections
/** * Copies all of the elements from one list into another. After the * operation, the index of each copied element in the destination list * is identical to its index In the source list. The destination * List must is at least as long as the source list. If It is longer, the * remaining elements in the destination list are unaffected.
<p> * * This is runs in linear time.
* * @param dest the destination list.
* @param src the source list.
* @throws indexoutofboundsexception If the destination list is too small * to contain the entire source list. * @throws unsupportedoperationexception If the destination list ' s * List-iterator does not support the
<tt>set</tt> operation. * * public static <T> void copy (LIST< Super t> dest, list< extends t> src) {int srcsize =
Src.size (); if (Srcsize > Dest.size ()) throw NEW indexoutofboundsexception ("Source does not fit in dest");
if (Srcsize < Copy_threshold | | (src instanceof randomaccess && dest instanceof randomaccess))
{for (int i=0; i<srcsize; i++) Dest.set (i, Src.get (i));
else {listiterator<? Super T> Di=dest.listiterator (); listiterator<?
Extends t> si=src.listiterator ();
for (int i=0; i<srcsize; i++) {di.next ();
Di.set (Si.next ()); }
}
}
SummaryWhy introduce generic wildcard characters. In a word: to ensure type safety.