原创转载请注明出处:http://agilestyle.iteye.com/blog/2376027
extends
The wildcard declaration of List<? extends Number> foo3 means that any of these are legal assignments:
List<? extends Number> foo3 = new ArrayList<Number>(); // Number "extends" Number (in this context) List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number List<? extends Number> foo3 = new ArrayList<Double>(); // Double extends Number
super
The wildcard declaration of List<? super Integer> foo3 means that any of these are legal assignments:
List<? super Integer> foo3 = new ArrayList<Integer>(); // Integer is a "superclass" of Integer (in this context) List<? super Integer> foo3 = new ArrayList<Number>(); // Number is a superclass of Integer List<? super Integer> foo3 = new ArrayList<Object>(); // Object is a superclass of Integer
PECS
Remember PECS: "Producer Extends, Consumer Super".
- "Producer Extends" - If you need a List to produce T values (you want to read Ts from the list), you need to declare it with ? extends T, e.g. List<? extends Integer>. But you cannot add to this list.
- "Consumer Super" - If you need a List to consume T values (you want to write Ts into the list), you need to declare it with ? super T, e.g. List<? super Integer>. But there are no guarantees what type of object you may read from this list.
- If you need to both read from and write to a list, you need to declare it exactly with no wildcards, e.g. List<Integer>.
example
Note how the source list src (the producing list) uses extends, and the destination list dest (the consuming list) uses super
public class Collections { public static <T> void copy(List<? super T> dest, List<? extends T> src) {} for (int i=0; i<src.size(); i++) { dest.set(i,src.get(i)); } } }
Reference
https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java