List values change if I change the array passed to Arrays.asList(array)

I have seen the code Arrays.class, but not able to understand why the changes made to the array is reflecting to ArrayList even though below code returns new ArrayList.

@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

Sample code:

    public class Test {
    public static void main(String[] args) {
        Integer [] array = {1,2,3,4,5};
        List<Integer> list = new ArrayList<>();
        list = Arrays.asList(array);
        System.out.println("List created from array:  " + list);
        array[0] = 100;
        System.out.println("List after changing array:" + list);
    }
}

Output:

List created from array: [1, 2, 3, 4, 5]

List after changing array:[100, 2, 3, 4, 5]

Answer

The list is backed by array as specified in document about Arrays.asList():

Returns a fixed-size list backed by the specified array. (Changes to the returned list “write through” to the array.)

And if you digging the line return new ArrayList<>(a) you will see:

private final E[] a; // This is internal array of List

ArrayList(E[] array) {
    a = Objects.requireNonNull(array);
}

public static <T> T requireNonNull(T obj) {
    if (obj == null)
        throw new NullPointerException();
    return obj; // Just return the array reference. No deep copy
}

So as you can see, the list does not copy the array data, just assign it reference to its internal array.

Hence your change to original array is reflected to the list and vice versa

Note that: Arrays.asList() return an instance of Arrays.ArrayList<>:

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable {
}

Unlike java.util.ArrayList, the List returned by Arrays.asList does not implement all of List functions. If you try to use methods like add(), it will throw UnsupportedOperationException

Leave a Reply

Your email address will not be published. Required fields are marked *