文章首发于:clawhub.club


在看ArrayList源码的时候,看到两个常量没理解:EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA

1
2
3
4
5
6
7
8
9
10
11
/**
* Shared empty array instance used for empty instances.
*/
private static final Object[] EMPTY_ELEMENTDATA = {};

/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

都是表示默认空数组,根据ArrayList的构造函数,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
// 注意这!!
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}

public ArrayList() {
// 注意这!!
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
// 注意这!!
this.elementData = EMPTY_ELEMENTDATA;
}
}

可以看出,只有无参构造用了DEFAULTCAPACITY_EMPTY_ELEMENTDATA常量,另外都是用了EMPTY_ELEMENTDATA。

再看add(int index, E element)、addAll(Collection<? extends E> c)、addAll(int index, Collection<? extends E> c)方法中调用的calculateCapacity:

1
2
3
4
5
6
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}

可以发现:如果是无参构造函数生成的ArrayList对象,在第一次怎加元素的时候,ArrayList初始容量是10。有参构造函数创建时,初始容量根据入参决定,如果要创建空数组,则都指向了EMPTY_ELEMENTDATA,
即减少了不必要的空数组。

理解:
这两个类常量都是空 Object 数组的引用,都代表 ArrayList 实例的空状态,也即是 elementData 数组中还没有元素。

  • EMPTY_ELEMENTDATA 是使用带初始化值的构造方法(有参构造函数,一个是指定初始容量,一个是指定初始集合)时使用的,
  • DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是使用默认的构造方法,也即是无参的构造方法时使用的。