Reputation: 11981
I understand the PECS concept and why the below add()
compile and don't compile:
List<? super ClassCastException> list = new ArrayList<>();
list.add(new ClassCastException()); // OK
list.add(new Exception()); // Does not compile
But shouldn't the below be illegal then? Why not? (specifying the super type that we can't add when instantiating)
List<? super ClassCastException> list2 = new ArrayList<Exception>(); // Compiles
^
Upvotes: 0
Views: 43
Reputation: 274690
Let's examine the reason why the first piece of code is illegal:
List<? super ClassCastException> list = new ArrayList<>();
list.add(new Exception()); // Does not compile
list
is of type List<? super ClassCastException>
i.e. a list of unknown type that is a parent of ClassCastException
. You can't put an Exception
in there because what if the list is actually a list of RuntimeExcept
? RuntimeException
is also a parent class of ClassCastException
isn't it? And you certainly can't put an Exception
in a list of RuntimeException
!
However, this is different:
List<? super ClassCastException> list2 = new ArrayList<Exception>();
What can you assign to list2
? list2
is declared as a list of unknown type that is a parent of ClassCastException
. Any kind of list that fits the criteria can be assigned.
"But there are other parent classes of ClassCastException
though!" you say. Well, yes there are, but in an assignment statement, do we care what the original value of list2
actually is? No. If list2
was originally an ArrayList<RuntimeException>
, fine. We can still assign an ArrayList<Exception>
. There is no contradiction here. See the italicised in the first paragraph? That's the contradiction that occurs if you try to put an Exception
in a list of ? super ClassCastException
. You can't point out anything wrong about this assignment statement though.
Upvotes: 1