If we have a Type[], we can only store Type or its subtypes in it. The same goes for ArrayList. So why is it said that one is homogeneous while the other is not?
Arrays have a runtime check on the type of the added element. That is, if a new element that is not of the same type is added, an ArrayStoreException
is thrown at runtime. That's why they are considered as "homegeneous".
This is not true for ArrayList
s (List
s in general). Due to type erasure at runtime, it can practically hold any object.
The following throws an exception when running:
Object[] array = new String[3];
array[0] = "a";
array[1] = 1; // throws java.lang.ArrayStoreException
unlike the following which compiles and runs without problem (although with a compiler warning as it doesn't properly use generics):
ArrayList list = new ArrayList<String>();
list.add("a");
list.add(1); // OK
list.add(new Object()); // OK
With a correct use of generics, i.e. declaring the variable list
above of type ArrayList<String>
instead of ArrayList
, the problem is avoided at compile-time:
ArrayList<String> list = new ArrayList<String>();
list.add("a");
list.add(1); // compilation error
list.add(new Object()); // compilation error
But even with a generically declared list, you can have something like this work without an exception at runtime:
ArrayList<String> list = new ArrayList<String>();
list.add("a");
Method[] methods = List.class.getMethods();
for(Method m : methods) {
if(m.getName().equals("add")) {
m.invoke(list, 1);
break;
}
}
System.out.println(list.get(0));
System.out.println((Object) list.get(1));
Output:
a
1