Why it compiles "List<String> lst; Object[] o = lst;" if List<String> is varargs?

170 Views Asked by At
public class VarargsParamVsLocalVariable {

    static void f(List<String>... stringLists) {
        // compiles fine! No problems in Runtime as well.
        Object[] array = stringLists; 
    }

    //but the same fails if List<String> is not a vararg parameter
    public static void main(String[] args) {
        List<String> stringLists; 
        List<String> stringLists1 = new ArrayList<>();
        //below lines give: "cannot convert from List<String> to Object[]"
        Object[] array = stringLists; // compile error!
        Object[] array1 = stringLists1; // compile error!
    }
}  

 // Why I can assign List<String> variable to Object[] variable if List<String> variable is a vararg parameter? 

Why I can assign List variable to Object[] variable if List variable is a vararg parameter?

6

There are 6 best solutions below

0
On

Any reference type varargs argument can be assigned to an Object array. In your particular case, each element of the Object array will be a List<String>.

Your code would be more clear (and type safe) if you changed the type of the array though :

static void f(List<String>... stringLists) {
    List<String>[] array = stringLists; 
}

This shows that you are not converting a List to an array. You just assign zero, one or multiple Lists to an array of Lists.

0
On

Because a Varargs like List<String>... stringLists is somehow equivalent to an array like List<String>[] stringLists.

To make your code compile you should create an array as next:

Object[] array1 = {stringLists1};

For stringLists, you will need to initialize it first otherwise even if you try to create an array as above it won't compile.

For the same reason public static void main(String[] args) { could be rewritten:

public static void main(String... args) {
1
On

Because Java didn't originally have varargs. They way they were added is by treating that varargs parameter as though it were an array.

Effectively, this

static void f(List<String>... stringLists)

...is the same as

static void f(List<String>[] stringLists)

...and so it's assignment-compatible with Object[].

0
On

Varargs is created as way of passing the arbitrary number of values to method . Previously it was being achieved by using array by putting value in that array.

So Varargs is just another option for achieving same, it just hides the process and developer don't need to create explicity array object.

So your List<String> ... varargs is actually List<String>[] and unlike generics, array supports all of this :-

   Parent[] par = new child[];
   Object[] objArray = new xyz[];

In your case :- Object[] o = lst = List<String>[] = List<String> ...

For more details javadocs

0
On

In this code:

static void f(List<String>... stringLists) {
    // compiles fine! No problems in Runtime as well.
    Object[] array = stringLists; 
}

stringLists is an array of List<String> (List<String>[]) but each List of this array is basically an Object.

So you have to know this, List<String> can be cast to an Object. Array of list (List[]) can be cast to an Object. Any array, list, hashtable... can be cast to an Object, it's why it pass without problem.

0
On

varargs is basically a syntactic sugar for an array i.e., the compiler will actually create and initialize the array of the vararg type (passed).

So, in your varargs f method, stringLists is the vararg which is actually an array (List<String>[]) and can be assigned to Object[]