这是指定初始容量的构造方法:
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 boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
这是用于扩容的部分代码:
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
 
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
现在我执行如下代码:
ArrayList list = new ArrayList(0);
list.add(1);
流程是这样的:
问题出在第二步,我发现 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 返回 true,请问这是为什么? EMPTY_ELEMENTDATA 和 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是两个不一样的对象:
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
|      1feiyuanqiu      2018-07-19 19:23:20 +08:00 『我发现 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 返回 true 』 你怎么发现的?如果是用 IDE 打断点看的,注意打断点的位置 | 
|  |      2vansl OP @feiyuanqiu  debug 之后确认的,确实进入了 if 后面的语句。 | 
|  |      3xmh51      2018-07-19 19:44:15 +08:00  1 @vansl 问题出现在 arraylist 是一个基础类。你打断点后看到的执行 calculateCapacity 并不是你传入的值的执行。不信你传入 2 试试? 断点应该打在  public boolean add(E e) {} 里面 | 
|      4feiyuanqiu      2018-07-19 19:48:00 +08:00 via Android  3 @vansl  如果用 IDE debug,不要直接在 add 方法处打断点,ArrayList 是个很基础的类,debug 启动过程很可能也会用到它 在 add 方法调用处断点,程序运行到这时,再进 add 方法里面断点,就能看到结果了 更简单的方法是复制 ArrsyList 的源码到一个新文件,然后用新的 ArrayList 来 debug,排除其他调用的干扰 | 
|  |      5vansl OP |