这是指定初始容量的构造方法:
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 = {};
1
feiyuanqiu 2018-07-19 19:23:20 +08:00
『我发现 elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 返回 true 』
你怎么发现的?如果是用 IDE 打断点看的,注意打断点的位置 |
2
vansl OP @feiyuanqiu
debug 之后确认的,确实进入了 if 后面的语句。 |
3
xmh51 2018-07-19 19:44:15 +08:00 1
@vansl 问题出现在 arraylist 是一个基础类。你打断点后看到的执行 calculateCapacity 并不是你传入的值的执行。不信你传入 2 试试? 断点应该打在 public boolean add(E e) {} 里面
|
4
feiyuanqiu 2018-07-19 19:48:00 +08:00 via Android 3
@vansl
如果用 IDE debug,不要直接在 add 方法处打断点,ArrayList 是个很基础的类,debug 启动过程很可能也会用到它 在 add 方法调用处断点,程序运行到这时,再进 add 方法里面断点,就能看到结果了 更简单的方法是复制 ArrsyList 的源码到一个新文件,然后用新的 ArrayList 来 debug,排除其他调用的干扰 |
5
vansl OP |