Difference between <? super T> and <? extends T>

原创转载请注明出处: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

 

 

猜你喜欢

转载自agilestyle.iteye.com/blog/2376027