java.util.Arrays.asList(T ...)如何工作?

时间:2014-08-04 05:21:06

标签: java arrays collections arraylist variadic-functions

乍一看似乎是一个愚蠢的问题,但我发现这个机制并非无足轻重。 JDK 8(从here复制)的实现只是几行:

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

重点是ArrayList中只有3个构造函数:

  • 一个不带任何参数
  • 一个人需要int(初始容量)
  • 一个需要Collection(元素),如下所示(从here复制):

public class ArrayList<E> extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{

    // ...

    transient Object[] elementData; // non-private to simplify nested class access

    private int size;

    // ...

    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);

    }

    // ...

}

由于唯一的可能性是调用第3个构造函数,似乎参数a(通用vararg)以某种方式“转换”为Collection。但据我所知,varargs只不过是语法较短的数组,并且不能转换为Collection s(所以这就是为什么这让我感到困惑)......

有人知道魔法是如何运作的吗?

谢谢!

3 个答案:

答案 0 :(得分:12)

您正在查看错误的ArrayList课程。 Arrays.asList(..)中使用的是java.util.Arrays.ArrayList,并且有一个接受数组的构造函数。

答案 1 :(得分:5)

此处描述的ArrayList类型不是java.util.ArrayList;它是在该文件中定义的私有类型(参见第3799行)。那个 有一个数组构造函数,它是Arrays.asList引用的那个。

希望这有帮助!

答案 2 :(得分:4)

Arrays.asList(...)会返回新的ArrayList。这是棘手的部分。 ArrayList不是java.util包中的那个,它实际上是static inner class类中的Arrays。检查此代码。

<强> Arrays.java

public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a);
}
// the static inner class is shown below.
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;

ArrayList(E[] array) {
        if (array==null)
            throw new NullPointerException();
    a = array;
}  

...    }