这是指定初始容量的构造方法:
public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.eementData = 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 ![]() @vansl 问题出现在 arraylist 是一个基础类。你打断点后看到的执行 calculateCapacity 并不是你传入的值的执行。不信你传入 2 试试? 断点应该打在 public boolean add(E e) {} 里面 |
4 feiyuanqiu 2018-07-19 19:48:00 +08:00 via Android ![]() @vansl 如果用 IDE debug,不要直接在 add 方法处打断点,ArrayList 是个很基础的类,debug 启动过程很可能也会用到它 在 add 方法调用处断点,程序运行到这时,再进 add 方法里面断点,就能看到结果了 更简单的方法是复制 ArrsyList 的源码到一个新文件,然后用新的 ArrayList 来 debug,排除其他调用的干扰 |
![]() | 5 vansl OP |