Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why java does not autobox int[] to Integer[]

When I do the following,

  • arrayList1 - contains one element and it is an int[].
  • arrayList2 - not compiling (Error : The constructor ArrayList<Integer>(List<int[]>) is undefined)
  • arrayList3 - contains 7 elements and they are Integer objects

Here's the code:

int[] intArray = new int[]{2,3,4,5,6,7,8};
ArrayList arrayList1 = new ArrayList(Arrays.asList(intArray));
ArrayList<Integer> arrayList2 = new ArrayList<Integer>(Arrays.asList(intArray));

Integer[] integerArray = new Integer[]{2,3,4,5,6,7,8};
ArrayList<Integer> arrayList3 = new ArrayList<Integer>(Arrays.asList(integerArray));

Question : Why doesn't the compiler auto-box the elements in the int[] to Integer and create an ArrayList<Integer>? What is the reason behind this? Is that my stupidity or some other reason?

like image 616
namalfernandolk Avatar asked Oct 22 '13 04:10

namalfernandolk


People also ask

What happens when an int is Autoboxed?

Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.

Do arrays autobox?

Arrays are never autoboxes or auto-unboxed, e.g. if you have an array of integers int[] x , and try to put its address into a variable of type Integer[] , the compiler will not allow your program to compile.

Why do we need Boxing in Java?

It is needed because of programmers easy to be able to directly write code and JVM will take care of the Boxing and Unboxing. Each of Java's 8 primitive type (byte,short,int,float,char,double,boolean,long) hava a seperate Wrapper class Associated with them.

How does Autoboxing of Integer work in Java?

For example, converting int to Integer class. The Java compiler applies autoboxing when a primitive value is: Passed as a parameter to a method that expects an object of the corresponding wrapper class. Assigned to a variable of the corresponding wrapper class.


2 Answers

The difference is int[] is itself an Object, whereas Integer[] is an array of references to Integer object.

Arrays.asList(T...) method takes variable arguments of some type T with no upper bounds. The erasure of that method is Arrays.asList(Object...). That means it will take variable number of arguments of any type that extends from Object.

Since int is not an Object, but a primitive type, so it can't be passed as individual element of T[], whereas int[] is an Object itself, it will go as first element of the T[] array (T... internally is a T[] only). However, Integer[] will be passed as T[], with each reference in Integer[] passed as different argument to T[].

And even if you would argue that compiler should have done the conversion from each element of int[] array to Integer, well that would be too much work for the compiler. First it would need to take each array element, and box it to Integer, then it would need to internally create an Integer[] from those elements. That is really too much. It already has a direct conversion from int[] to Object, which it follows. Although I have always wished Java allowed implicit conversion from int[] to Integer[], that would have made life simpler while working with generics, but again, that's how the language is designed.

Take a simple example:

Object[] array = new Integer[10];  // this is valid conversion
Object[] array2 = new int[10];     // this is not
Object obj = new int[10];          // this is again a valid conversion

So, in your code Arrays.asList(intArray) returns a ArrayList<int[]> and not ArrayList<Integer>. You can't pass it to the ArrayList<Integer>() constructor.


Related:

  • int[] and Integer[]: What is the difference?
like image 76
Rohit Jain Avatar answered Oct 12 '22 18:10

Rohit Jain


An int[] is not the same as an Integer[].

An array has as associated Class object. The class object for an array of primitive ints is [I. The class object for an array of Integer is [Ljava/lang/Integer.

An array is itself an object, so converting between two objects of the same type is an identity conversion. Converting between two different typed objects isn't - and int[] and Integer[] are definitely different, as evidenced by the bytecode above.

Lastly, bear in mind that autoboxing would only really apply if there was an associated boxing conversion.

like image 44
Makoto Avatar answered Oct 12 '22 18:10

Makoto