Why is adding a subclass a of type in a collection is illegal?
题
given this code snippet
//Creates a list of List numbers
List<List<Number>> num = new ArrayList<List<Number>>();
//Creates a list of List doubles
List<List<Double>> doub = new ArrayList<List<Double>>();
//List of doubles
List<Double> d = new ArrayList<Double>();
d.add(2.5);
d.add(2.6);
doub.add(d);
num.add(d);//This code will not compile
Why is that num.add(doub) will not be allowed? isn't List<List<Number>>
a super type of
List<List<Double>>
?
解决方案
Generics inheritance is little different than our understanding of inheritance. If you would like to use subclass types you need to define bounds (wildcards) using either extends (or) super in generics.
其他提示
You are trying to add a List of Lists to a List that takes a List. (not after edit I see)
Or maybe a bit less confusing:
Your num list can only add List<Number>, you are trying to add a List<List<Double>>.
Also, inheritance with generics doesn't work that way, even if you did add a List of doubles, it would not work.
If you define num like this:
List<List<? extends Number>> num = new ArrayList<List<? extends Number>>();
Then you will be able to do this:
num.add(d);
but not:
num.add(doub);
List<Double>
doesn't have anything to do with List<Number>
as far as the compilre is concerned about the List<>
part.
Therefore List<List<Double>>
does not inherit from List<List<Number>>
they are two completely different types by the Java Generics system. This is not an extends
relationship as when building classes.
Given the declared types, doub.add(d)
and num.add(doub)
imply inconsistent behavior of add()
. If doub.add(d)
works, I wouldn't expect num.add(doub)
to as well.
Did you perhaps mean to test
num.add(d)
instead of
num.add(doub)
?