一.源代码
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;
如上面代码,其中elementData是实际存储元素的数组.
而EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA则是用于存储空数组的
那么他俩的区别在什么地方呢,为什么要创建两个性质差不多的数组呢?
二.缘由
首先我们要知道这两个空数组是在什么时候被使用的,翻阅源代码,如下
EMPTY_ELEMENTDATA
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);
}
}
DEFAULTCAPACITY_EMPTY_ELEMENTDATA
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
这时可以知道,在构造ArrayList的时候,如果使用的是有参构造而且传入的容量为0,使用的便是EMPTY_ELEMENTDATA。
但是如果使用的是无参构造,使用的便是DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
使用EMPTY_ELEMENTDATA的时候,容量为0(添加元素的时候会有一个+1操作,得到minCapacity,确保不会超过容量而报错)
使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA的时候它容量又是多少呢?翻看源代码如下
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
可见当为DEFAULTCAPACITY_EMPTY_ELEMENTDATA的时候,会使用DEFAULT_CAPACITY和minCapacity的最大值,第一次便是用DEFAULT_CAPACITY,即使用的容量为10.
所以DEFAULTCAPACITY_EMPTY_ELEMENTDATA的作用就在于添加元素的时候判断它是否是创建时候的空数组,如果是的话,给他一个为10的容量
那按照这么来完全一个DEFAULTCAPACITY_EMPTY_ELEMENTDATA就够了,为啥还要一个EMPTY_ELEMENTDATA呢?
其实JDK1.7的时候就是这么做的.
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
在无参构造的情况下使用EMPTY_ELEMENTDATA的代替了如今的DEFAULTCAPACITY_EMPTY_ELEMENTDATA
但是在有参构造的情况下只要initialCapacity>0就创建一个Object数组
这样会导致创建大量的空数组
三.结论
所以我们可以得出使用DEFAULTCAPACITY_EMPTY_ELEMENTDATA是为了得知它是否是无参构造创建,是的话给他一个初始容量10
而使用EMPTY_ELEMENTDATA是为了避免创建大量的空数组
但是在两种情况(有参和无参)下被使用的,所以创建两个空数组