为什么列表不能用数组初始化,没有arrays.aslist()?

cjL*_*Lee 2 java arrays arraylist

Arrays.asList() 声明如下。

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

因此,如您所知,要List使用数组初始化混凝土,您可以这样做:

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

但这又如何呢?

List<String> list = new ArrayList<>(new String[]{"hello", "world"});
Run Code Online (Sandbox Code Playgroud)

我预计它会起作用,但没有。

我明白为什么。这是因为ArrayList需求Collection类的构造函数之一。

那么,呢Arrays.asList()

Varargs 被编译为数组,因此该方法可能会编译如下。

String[] strings = new String[] {"hello", "world"};
List<String> list = new ArrayList<>(Arrays.asList(strings));
Run Code Online (Sandbox Code Playgroud)

但它实际上返回ArrayList对象。为什么这是可能的?

Swe*_*per 5

确实,Arrays.asList 正如你所说的那样实现,但ArrayList实际上并不是指java.util.ArrayList我们都知道和喜爱的。它指的是类中的一个私有内部Arrays类。从第一个链接,就在 的声明下asList,您将看到:

/**
 * @serial include
 */
private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{
    ...
Run Code Online (Sandbox Code Playgroud)

new ArrayList<>(a)指的是上面的类。上面的类有一个构造函数,它接受一个E[]

    ArrayList(E[] array) {
        if (array==null)
            throw new NullPointerException();
        a = array;
    }
Run Code Online (Sandbox Code Playgroud)

但是java.util.ArrayList类没有这样的构造函数,难怪你不能这样做:

List<String> list = new ArrayList<>(new String[]{"hello", "world"});
Run Code Online (Sandbox Code Playgroud)

java.util.ArrayList和之间的另一个很大区别java.util.Arrays$ArrayList是您可以向前者添加/删除元素,但不能向后者添加/删除元素。例如,这会引发异常:

Arrays.asList("a", "b", "c").add("d");
Run Code Online (Sandbox Code Playgroud)