问题说明
- 今天在写代码的时候发现了一个List有参构造函数的问题。
//部分ArrayList源码
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
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);
}
}
在调用上面的这个构造函数初始化的时候,函数内部只会为存储的数组对象elementData 赋值,而不会对size进行赋值,而size变量是int类型默认值为0。
- 再来看看ArrayList另一段源码
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
在调用set方法为某个指定下标元素赋值的时候,会去判断传入的下标是否超过List的大小,由于这时候size是0,所以必定会抛出异常。
结论
- 不是很理解这个构造方法为什么这么设计(也许是为了节约内存),如果需要初始化size正常的List对象可以使用下面的方法。
Arrays.asList(new Object[1024]);
//指定类型
new ArrayList<>(Arrays.asList(new Object[1024]));