I don't understand why the following does not work:
public void doSomething(int... args){ List<Integer> broken = new ArrayList<Integer>(Arrays.asList(args)) }
Its my understanding that the compiler converts the "int... args" to an array, so the above code should work.
Instead of working I get:
cannot find symbol symbol: constructor ArrayList(java.util.List
<int[]
>) location: class java.util.ArrayList<java.lang.Integer
>
Thats bizarre. I'm not adding an array to array list, I'm adding each element from the list to the arraylist. Whats going on?
Varargs are useful for any method that needs to deal with an indeterminate number of objects. One good example is String. format . The format string can accept any number of parameters, so you need a mechanism to pass in any number of objects.
Passing an ArrayList to method expecting vararg as parameter To do this we need to convert our ArrayList to an Array and then pass it to method expecting vararg. We can do this in single line i.e. * elements passed.
While using the varargs, you must follow some rules otherwise program code won't compile. The rules are as follows: There can be only one variable argument in the method. Variable argument (varargs) must be the last argument.
Every time we use varargs, the Java compiler creates an array to hold the given parameters. In this case, the compiler creates an array with generic type components to hold the arguments. The varargs usage is safe if and only if: We don't store anything in the implicitly created array.
Java cannot autobox an array, only individual values. I would suggest changing your method signature to
public void doSomething(Integer... args)
Then the autoboxing will take place when calling doSomething
, rather than trying (and failing) when calling Arrays.asList
.
What is happening is Java is now autoboxing each individual value as it is passed to your function. What you were trying to do before was, by passing an int[]
to Arrays.asList()
, you were asking that function to do the autoboxing.
But autoboxing is implemented by the compiler -- it sees that you needed an object but were passing a primitive, so it automatically inserted the necessary code to turn it into an appropriate object. The Arrays.asList()
function has already been compiled and expects objects, and the compiler cannot turn an int[]
into an Integer[]
.
By moving the autoboxing to the callers of your function, you've solved that problem.
You can do
public void doSomething(int... args){ List<Integer> ints = new ArrayList<Integer>(args.length); for(int i: args) ints.add(i); }
or
public void doSomething(Integer... args){ List<Integer> ints = Arrays.asList(args); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With