一 类图
实现了RandomAccess接口,可以随机访问
实现了Cloneable接口,可以克隆
实现了Serializable接口,可以序列化、反序列化
实现了List接口,是List的实现类之一
实现了Collection接口,是Java Collections Framework成员之一
实现了Iterable接口,可以使用for-each迭代
属性
// 序列化版本UID
private static final long
serialVersionUID = 8683452581122892189L;
/**
- 默认的初始容量
*/
private static final int
DEFAULT_CAPACITY = 10;
/**
- 用于空实例的共享空数组实例
- new ArrayList(0);
*/
private static final Object[]
EMPTY_ELEMENTDATA = {};
/**
- 用于提供默认大小的实例的共享空数组实例
- new ArrayList();
*/
private static final Object[]
DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
- 存储ArrayList元素的数组缓冲区
- ArrayList的容量,是数组的长度
- non-private to simplify nested class access
*/
transient Object[] elementData;
/**
- ArrayList中元素的数量
*/
private int size;
方法
构造方法
带初始容量的构造方法
/**
- 带一个初始容量参数的构造方法
- @param initialCapacity 初始容量
- @throws 如果初始容量非法就抛出
-
IllegalArgumentException
*/
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);
}
}
如果initialCapacity < 0,就创建一个新的长度是initialCapacity的数组
如果initialCapacity == 0,就使用EMPTY_ELEMENTDATA
其他情况,initialCapacity不合法,抛出异常
无参构造方法
/**
- 无参构造方法 将elementData 赋值为
- DEFAULTCAPACITY_EMPTY_ELEMENTDATA
*/
public ArrayList() {
this.elementData =
DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
带一个集合参数的构造方法
/**
-
带一个集合参数的构造方法
-
@param c 集合,代表集合中的元素会被放到list中
-
@throws 如果集合为空,抛出NullPointerException
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
// 如果 size != 0
if ((size = elementData.length) != 0) {
// c.toArray 可能不正确的,不返回 Object[]
// https://bugs.openjdk.java.net/browse/JDK-6260652
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(
elementData, size, Object[].class);
} else {
// size == 0
// 将EMPTY_ELEMENTDATA 赋值给 elementData
this.elementData = EMPTY_ELEMENTDATA;
}
}
使用将集合转换为数组的方法
为了防止c.toArray()方法不正确的执行,导致没有返回Object[],特殊做了处理
如果数组大小等于0,则使用 EMPTY_ELEMENTDATA
那么问题来了,什么情况下c.toArray()会不返回Object[]呢?
public static void main(String[] args) {
List list = new ArrayList<>(Arrays.asList(“list”));
// class java.util.ArrayList
System.out.println(list.getClass());Object[] listArray = list.toArray();
// class [Ljava.lang.Object;
System.out.println(listArray.getClass());
listArray[0] = new Object();System.out.println();
List asList = Arrays.asList(“asList”);
// class java.util.Arrays$ArrayList
System.out.println(asList.getClass());Object[] asListArray = asList.toArray();
// class [Ljava.lang.String;
System.out.println(asListArray.getClass());
// java.lang.ArrayStoreException
asListArray[0] = new Object();
}
我们通过这个例子可以看出来,java.util.ArrayList.toArray()方法会返回Object[]没有问题。而java.util.Arrays的私有内部类ArrayList的toArray()方法可能不返回Object[]。
为什么会这