Why can’t we read from contravariance type

Sundaravel :

I’m learning generics in Java, and I am learning Covariance and contravariance. I understood covariance and why can’t we write in to covariance type. But for me contravariance is confusing. I want to know why reading from contravariance is always Object type

Lets say we have the following classes

Class Animal
Class Dog extends Animal
Class Tiger extends Animal

Now, consider the following code

List<Animal> animals = new ArrayList<>();
List<? super Animal> contraVarianceList=animals;

animals.add(new Dog()); // Allowed
animals.add(new Tiger()); //Allowed
Animal animal = contraVarianceList.get(0); // Not allowed. Why?

My question is why cant we read “Animal” from the contravariance list. Why is it always and only “Object” that can be returned? What will or may go wrong if we read “Animal” from the contravariance list?

jbx :

I presume you meant to ask why is Animal animal=contraVarianceList.get(0); not allowed.

Think about it this way:

List<Animal> animals=  new ArrayList<>();
List<Object> objects = new ArrayList<>();

List<? super Animal> contraVarianceList = animals;
List<? super Animal> contraVarianceList2 = objects;

animals.add(new Dog()); // Allowed
animals.add(new Tiger()); //Allowed

objects.add(new Dog()); // Allowed
objects.add(new Tiger()); //Allowed

//there is no type difference between contraVarianceList and contraVarianceList2
Animal animal = contraVarianceList.get(0);  //compiler will complain
Animal animal2 = contraVarianceList2.get(0); //compiler will complain

The compiler cannot really know that any of them is carrying only Animal instances. You explicitly said ? super Animal so it could also be List that is carrying plain Object.

Usually you use these types of lists for parameters of methods where you are expecting to add items rather than read from the list. So having something like this:

void populateAnimals(List<? super Animal> animals) {
  //whatever code
  animals.add(...);
}

Guarantees that you can use the method with both List<Object> and List<Animal>.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=142917&siteId=1