Thanks for your reply.
List< ? super Dog> list can be assigned to new ArrayList<Animal> or ArrayList<Dog> or ArrayList<Object>.
Therefore,
case 1 : list = new ArrayList<Animal>();
case 2 : list = new ArrayList<Dog>();
case 3 : list = new ArrayList<Object>();
will all compiled.
However, when we attempt to add items to the list, only Dog object can be added.
The compiler is designed in this way, because it needs to prevent the programmers to add a Cat to list or any object like a
String to the list as a Cat is not above Dog and a String is not above Dog.
Suppose,
case 1:
Animal cat = new Cat();
list.add(cat) , won't compile even though list is assigned to a list with Animal object inside it.
case 3:
Object o = new String();
list.add(o), won't compile even though list is assigned to a list with Object inside it.
Correct me if I am wrong.