Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics -- Assigning a list of subclass to a list of superclass

Tags:

java

generics

I have a basic question regarding assignment of a list of subclass to a list of superclass.

So I have something like the following:

Class B extends A;

List <B> bList = new ArrayList<B>();
List <A> aList = bList; 

Why does this last assignment fail? Sorry for the newbie question

like image 997
user294280 Avatar asked Jun 07 '11 05:06

user294280


4 Answers

To explain this, let me substitute "B" with Integer and "A" with Number. This is just to make it a little easier to explain.

Class Integer extends Number;

List <Integer> iList = new ArrayList<Integer>();
List <Number> nList = iList // will fail

The reason this would fail is because nList can take any Number -- it can take Integer, it can take Double, or for that matter any subclass of Number. However, this is not true for iList. You cannot add a Double to iList because it accepts only Integer and its subclasses. Hope this helps explain it to you.

like image 55
Sai Avatar answered Nov 14 '22 21:11

Sai


When you declare a List of items of type A, only items of type A can be added or removed from the List. If you need to include subclasses of A, use the generic wildcard ? extends A to indicate so. Your code should therefore be:

List <? extends A> aList = bList; 
like image 35
Vineet Reynolds Avatar answered Nov 14 '22 22:11

Vineet Reynolds


List<B> is not List<A>:

Through example: let say you have class B1 extends A{} and class B2 extends A{} then (if you would be able to do that:

List<B1> b1 = new AList<B1>();
List<A> a = b1;

List<B2> b2 = new AList<B2>();

by the hypothesis, you should be able to do a.add(new B2()) but this is wrong.

If you try the same thing but using arrays instead of lists, it will compile and throw exception in runtime.

We say that arrays are covariant and generics are invariant.

to make the code compile you have the wite it:

List<? extends A> a = b;

this says that a is a list of some subtype of A. _But you don know which one. Because of that you can't do a.put(X)

like image 20
Op De Cirkel Avatar answered Nov 14 '22 21:11

Op De Cirkel


List<B> and List<A> are invariant type. What you need is covariant type. In this case, it is List<? extends A>.

like image 28
Prince John Wesley Avatar answered Nov 14 '22 21:11

Prince John Wesley