[海中灯塔]ArrayList源代码解析-EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA的区别

一.源代码

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是为了避免创建大量的空数组

但是在两种情况(有参和无参)下被使用的,所以创建两个空数组

posted @ 2021-03-17 17:38  海中灯塔  阅读(185)  评论(0编辑  收藏  举报