关于ArrayList实现中ensureCapacity方法内oldData变量作用的疑问
关于ArrayList中ensureCapacity方法里oldData数组的解惑
嘿,这个问题我当初啃ArrayList源码的时候也琢磨过好一阵!先别急着觉得它没用,咱们得结合JDK的版本演变来看:
首先,我猜你看到的代码大概是这样的(早期JDK版本里的实现):
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; elementData = Arrays.copyOf(elementData, newCapacity); } }
为什么会有oldData?
在JDK 1.5引入Arrays.copyOf方法之前,ArrayList的扩容逻辑是手动创建新数组+显式复制元素,核心代码大概是这样:
// 早期版本的扩容核心逻辑 Object newData[] = new Object[newCapacity]; System.arraycopy(oldData, 0, newData, 0, oldCapacity); elementData = newData;
这时候oldData就扮演了关键角色:它保存了原数组elementData的引用,确保在复制过程中能准确拿到扩容前的数组内容——毕竟如果在计算新容量的间隙,elementData被其他操作修改(虽然ArrayList本身不是线程安全的,但早期代码还是考虑了这种细节),oldData能保证复制的是扩容前的原始数据。
现在看起来没用的原因
后来JDK封装了Arrays.copyOf方法,这个方法内部已经把“创建新数组+复制原数组元素”的逻辑整合在一起了,只需要传入原数组elementData和新容量就能完成扩容。这时候显式声明oldData变量就显得多余了,因为Arrays.copyOf会直接使用elementData的当前值来复制。
有些旧版的源码或者教程还保留了这个变量,其实是历史遗留的代码痕迹——就像老房子里的旧家具,虽然现在用不上了,但能看出当初的设计逻辑。
总结
简单来说:oldData是早期手动数组复制逻辑的产物,在引入Arrays.copyOf后的实现里确实没有实际作用,但它见证了ArrayList扩容逻辑的简化过程。
内容的提问来源于stack exchange,提问作者Jacobian
相关产品推荐
相关产品推荐

