In my understanding
public static <T> void addandDisp(Collection<T> cs, T t)
{
for (T o : cs)
{
s.add(o);
}
for (T o : cs)
{
System.out.println(o);
}
}
this method expect a T Collection and T object
//call 1
List<? super Object> ls1 = new LinkedList<Object>();
addandDisp(ls1,new String());
// error free because it will give an Object (include superclasses, if any) Collection and String. Since String is a subclass of Object or whatever is superclasses, calling the method like this will use widening/upcasting.
//call 2
List<? extends Object> ls2 = new LinkedList<Object>();
addandDisp(ls2,new Object());
// will error because the type of ls2 is anything than extends Object inclusive and an Object. Since in the method declaration the parameter cs is not type a Collection of anything than extends Object inclusive, the compiler sees that there is a possibity the type in cs might be different with the type of t. In compile time the compile prevent something like this (Collection<String> cs,Object t)
//call 3
List<Object> ls3 = new LinkedList<Object>();
addandDisp(ls3,new String());
// same as number one it will use widening/upcasting for String class.
//call 4
List<? super Object> ls4 = new LinkedList<Object>();
addandDisp(ls4,new Object());
// same reason as number 1 and 3