Dero Leaq
Dero Leaq

Reputation: 13

Why can ArrayLists store different object while arrays cannot?

Putting different types of Objects into an array will throw an ArrayStoreException, while putting different types of objects into an ArrayList works.

As far as I know, the ArrayList is built on top of an array, so why does it work there? Is it implemented differently?

I searched but found no answer.

Upvotes: 1

Views: 230

Answers (2)

ajb
ajb

Reputation: 31699

An ArrayStoreException can only arise when you've cast an array SomeClass[] to an array TheSuperClass[]. It doesn't get thrown in other situations. For example:

A[] array = new A[100];

The elements of array can be objects of class A or any subclass of A, and you'll never get ArrayStoreException. Similarly:

Object[] array = new Object[100];

The elements of this array can be anything. No matter what you assign array[n] to, this won't throw an ArrayStoreException.

The issue comes when you use new to create an array of one type, and then cast it (perhaps implicitly) to an array of some superclass type:

A[] array = new B[100];   // legal if B is a subclass of A
C[] array2 = new C[100];  
Object[] array3;
array3 = array2;          // legal even though `array2` is C[]

This kind of cast is legal. BUT if you then try to assign something that doesn't fit into the type used to create the array, you'll get ArrayStoreException.

array[1] = new A();

The only things that can be assigned into array[n] are B or subclasses of B. The compiler can't catch the above error at compile time, but it throws an exception at runtime.

array3[1] = "some string";

Even though array3 is an Object[] array, you can't assign any old object to its elements; they have to be C or subclasses of C.

The reason this isn't a problem with ArrayList is that you just can't do the same kind of cast.

ArrayList<A> array = new ArrayList<B>();   // illegal even if B is a subclass of A
ArrayList<C> array2 = new ArrayList<C>();
ArrayList<Object> array3;
array3 = array2;  // illegal

So it's not really a matter of arrays being more restricted than ArrayList. Arrays have an exception in a situation that just can't come up with ArrayLists.

EDIT (based on Luiggi's comment): OK, it looks like you can force the wrong kind of object into an ArrayList with some trickery:

((ArrayList)array2).add(x);

where x can have any type; it doesn't have to be of type C. But never, never, never do this. Especially in any program I might have to maintain one day.

Upvotes: 2

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85809

ArrayList has a field called Object[] elementData which means an ArrayList supports adding every kind of object reference. This also means that ArrayList doesn't support primitive types such as int or char, but instead their wrapper classes Integer and Character, respectively.

Arrays are usually for single-type elements since their declaration, unless you declare them as Object[]. For primitive types, there's no generic array, just the arrays of primitives int[], char[] and on...


if you create an Object[] array, and put in strings and afterwards a date object, it will throw an exception

Here's a code that proves the contrary, compiles and executes with no problem by having an Object[] storing Strings and a Date:

Object[] objects = { "hello", "world", new Date() };
System.out.println(Arrays.toString(objects));

Output (the Date will depend on the current time of your pc):

[hello, world, Tue Aug 12 00:09:00 GMT 2014]

You can check it working here.

Upvotes: 7

Related Questions