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

3

18

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?

Microtome answered 18/4, 2016 at 17:24 Comment(2)
Who told you ArrayLists are inhomogeneous? As long as you don't bypass the generics, they're exactly as homogeneous as arrays. (If you do bypass the generics, then you should probably be comparing to Object[].)Gilud
Every element of any array has to be the same primitive type or the same reference type. Every element of an ArrayList has to be the same reference type.Assumpsit
S
28

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

Snooty answered 18/4, 2016 at 17:26 Comment(3)
Could you embed the "bypassing of generics" and show with generics it is indeed homogeneous into the answer?Parachronism
"The following compiles and runs without problem" While this will compile, you will get a warning while compiling it.Carnelian
Thanks for posting, it running successfully in JDK8 but not in 17. I get Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at com.example.demo.DemoApplication.main(DemoApplication.java:17)Indecorous
M
3

Yes.Java Arrays are homogeneous,because when you declare any array in Java you have to declare its type. eg:

int arr[]; //type is int
    String arr[]; //type is String
    float arr[]; //type is float

now if you try to store any other data-type in declared array,it will be a compile time error. eg:

 int arr=new int[5];
     arr[0]="I am a String not int"; //compile time error

but ArrayList are the Collection's part,they hold Objects,instead of any specific data-type[if we are not talking about generics],and because every thing in java is directly or indirectly inherited from Object class,so It will not give you compile-time error,type checking will be on run-time.

eg:

 ArrayList al=new ArrayList();//type is Object
    al.add("I am a String");  //Bacause String class in inherited from Object Class
    al.add(1);//the int 1 will first autobox into Integer class then stored in al ArrayList.Now bacause Integer class is also inherited from Object class,it will*/ allow you to store
    al.add(UserDefinedClass); //because every User defined class is also inherited from Object class,so it will also allow you.

Now did you notice,because we have not defined any data type of ArrayList al,but still we are storing different type values: this is know why ArrayList Stores Object not specific data-type,thus they are heterogeneous not homogeneous.

Mabel answered 19/4, 2016 at 11:52 Comment(0)
S
0
import java.util.ArrayList
class ArrayDemo{
public static void main(String[] args){
    // ARRAYS ARE HOMOGENEOUS
    int[] arr = new int[2];
    arr[0] = 10;
    arr[1] = 10.2    // COMPILATION ERROR

    // BUT ARRAYLISTS ARE NOT
    ArrayList array = new ArrayList();
    array.add(Integer.valueOf(10));
    array.add(Double.valueOf(10.2));    // NO COMPILATION ERROR
}

}

Sleekit answered 18/12, 2023 at 12:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.