It seems to be a silly question at the first sight, but I found that the mechanism isn't trivial. The implementation from JDK 8
(copied from here) is just a few lines:
这看起来似乎是一个愚蠢的问题,但我发现这个机制并非无足轻重。 JDK 8的实现(从这里复制)只是几行:
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
The point is that there are only 3 constructors in ArrayList
:
关键是ArrayList中只有3个构造函数:
- one doesn't take any parameter
- one takes an
int
(the initial capacity) - one takes a
Collection
(the elements) as shown below (copied from here):
一个不带任何参数
一个拿一个int(初始容量)
一个采取如下所示的集合(元素)(从这里复制):
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);
}
// ...
}
Since the only possibility is that the 3rd constructor is called, it seems that the parameter a
(the generic vararg) is somehow "casted" to a Collection
. But as far as I know, varargs are nothing more than arrays with a shorter syntax, and are not convertible to Collection
s (so that's why this made me puzzled)...
由于唯一的可能性是调用第3个构造函数,似乎参数a(通用vararg)以某种方式“转换”到Collection。但据我所知,varargs只不过是语法较短的数组,并且不能转换为Collections(这就是为什么这让我感到困惑)...
Does anybody know how the magic works?
有谁知道魔法是如何运作的?
Thank you!
3 个解决方案
#1
12
You're looking at the wrong ArrayList
class. The one used in Arrays.asList(..)
is java.util.Arrays.ArrayList
and has a constructor that accepts an array.
您正在查看错误的ArrayList类。 Arrays.asList(..)中使用的是java.util.Arrays.ArrayList,并且有一个接受数组的构造函数。
#2
5
The ArrayList
type that's described here is not java.util.ArrayList
; it's a private type defined inside that file (see line 3799). That one does have an array constructor, and it's the one referenced by Arrays.asList
.
这里描述的ArrayList类型不是java.util.ArrayList;它是在该文件中定义的私有类型(参见第3799行)。那个确实有一个数组构造函数,它是Arrays.asList引用的那个。
Hope this helps!
希望这可以帮助!
#3
4
Arrays.asList(...)
returns a new ArrayList
. Here's the tricky part. The new ArrayList
is not the one in the java.util
package, it is actually a static inner class
in Arrays
class. Check this code.
Arrays.asList(...)返回一个新的ArrayList。这是棘手的部分。新的ArrayList不是java.util包中的那个,它实际上是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;
}
... }
#1
12
You're looking at the wrong ArrayList
class. The one used in Arrays.asList(..)
is java.util.Arrays.ArrayList
and has a constructor that accepts an array.
您正在查看错误的ArrayList类。 Arrays.asList(..)中使用的是java.util.Arrays.ArrayList,并且有一个接受数组的构造函数。
#2
5
The ArrayList
type that's described here is not java.util.ArrayList
; it's a private type defined inside that file (see line 3799). That one does have an array constructor, and it's the one referenced by Arrays.asList
.
这里描述的ArrayList类型不是java.util.ArrayList;它是在该文件中定义的私有类型(参见第3799行)。那个确实有一个数组构造函数,它是Arrays.asList引用的那个。
Hope this helps!
希望这可以帮助!
#3
4
Arrays.asList(...)
returns a new ArrayList
. Here's the tricky part. The new ArrayList
is not the one in the java.util
package, it is actually a static inner class
in Arrays
class. Check this code.
Arrays.asList(...)返回一个新的ArrayList。这是棘手的部分。新的ArrayList不是java.util包中的那个,它实际上是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;
}
... }