在阅读Java6 集合类源码ArrayList中遇到了这样一个方法:
ArrayList.java
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);
}
}
函数作用是对ArrayList
扩容,当新的容量大于原来的ArrayList
容量时,便使用Arrays.copyOf()
进行扩容操作,很简单的函数。
但是如果仔细观察的话会发现它声明了一个局部变量oldData
,但在后面的代码中并没有使用。为什么要声明这个局部变量,是疏忽还是其他的目的?
乍一看来后面并没有用到关于oldData
局部变量,这句话显得多此一举!但是这是一个牵涉到内存管理的类,所以要了解内部的问题。而且为什么这一句还在if的内部,这跟elementData=Arrays.copyOf(elementData,newCapacity);
这句是有关系的,下面这句Arrays.copyOf()
的实现时新创建了newCapacity
大小的内存,然后把老的elementData
放入。好像也没有用到oldData
,有什么问题呢。问题就在于旧的内存的引用是elementDataelementData
指向了新的内存块,如果有一个局部变量oldData
变量引用旧的内存块的话,在copy的过程中就会比较安全,因为这样证明这块老的内存依然有引用,分配内存的时候就不会被侵占掉,然后copy完成后这个局部变量的生命期也过去了,然后释放才是安全的。不然在copy的的时候万一新的内存或其他线程的分配内存侵占了这块老的内存,而copy还没有结束,这将是个严重的事情。