Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does casting an ArrayList 's generic to a superclass not work?

Can someone please explain to me why the line marked //this line gives a compile error (why?) in the following code sample does not work?

import java.util.ArrayList;

public class GenericCastCheck {

    class A{
    }

    class B extends A{
    }

    public static void main(String[] args) {

        A aObject = new A();
        B bObject = new B();

        //this line works fine
        aObject = bObject;
        //this line gives a compile (expected)
        bObject = aObject;

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

        //this line gives a compile error (why?)
        aList = bList;
        //this line gives a compile error (expected)
        bList = aList;
    }
}

Specifically, when we say that bList is of type ArrayList<B>, does it not mean that each element of it is an instance of B? If so, then what is the problem in casting it to ArrayList<A>, if we can cast individual instances of B to A?

Thanks.

like image 216
Animesh Avatar asked May 18 '11 12:05

Animesh


People also ask

Why generic arrays are not allowed?

If generic array creation were legal, then compiler generated casts would correct the program at compile time but it can fail at runtime, which violates the core fundamental system of generic types.

Can ArrayList be generic?

Both ArrayList and vector are generic types.

Why ArrayList is not good for manipulation?

Manipulating ArrayList takes more time due to the internal implementation. Whenever we remove an element, internally, the array is traversed and the memory bits are shifted. Manipulating LinkedList takes less time compared to ArrayList because, in a doubly-linked list, there is no concept of shifting the memory bits.

Can you cast an ArrayList Java?

You can't. An ArrayList<Object> is not an ArrayList<User> even if the first one contains all User objects.


1 Answers

The problem is this:

ArrayList<A> aList = new ArrayList<A>();
ArrayList<B> bList = new ArrayList<B>();
aList = bList; // if this were valid...
aList.add(new A()); // ...what should happen here?
B b = bList.get(0); // ...and here?

If you do the same thing with arrays, you get an ArrayStoreException in line 4 at runtime. For generic collections, it was decided to prevent that kind of thing at compile time.

like image 75
Michael Borgwardt Avatar answered Oct 21 '22 04:10

Michael Borgwardt