Search code examples
javaarraysarraylistdata-structurescollections

What does it mean that Java arrays are homogeneous, but ArrayLists are not?


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?


Solution

  • 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 ArrayLists (Lists 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