4

While learning Java generics I came to know that with covariance we can read items from a structure, but we cannot write anything into it and with contravariance we can write items into a structure, but we cannot read anything from it.

Let's take an example :

List<? extends Number> myNums = new ArrayList<Integer>();
myNums.add(45L); // Covariance - compiler error
List<? super Integer> myNums = new ArrayList<Integer>();
myNums.add(1);
Number myNum = myNums.get(0); //Contravariance - compiler-error

What I am not able to understand is why is this thing prohibited ? I am not able to understand what can go wrong if this thing is allowed to happen ?

Number945
  • 4,631
  • 8
  • 45
  • 83
  • newArrayList need to be new ArrayList – Maytham Fahmi Mar 18 '17 at 12:25
  • 2
    This talks about what can go wrong with covariance: http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p?rq=1 – Jorn Vernee Mar 18 '17 at 12:25
  • Well actually the article you linked explains exactly that question. Do you have any concrete questions in regard to these explanation? – user140547 Mar 18 '17 at 12:26
  • And your own code shows it, too. it tries to add a Long (45L) to a List. if it was allowed, the list wouldn't be type-safe anymore, since you would store a Long into a List. – JB Nizet Mar 18 '17 at 12:28

1 Answers1

4

You cannot add element of Integer class into List<? extends Number> because you don't know exact type of elements in the list. It may be actually List<Double>. The same logic in the next example. What you get from List<? super Integer> may have Object type, not the Number.

Zefick
  • 2,014
  • 15
  • 19