ArrayList源码解析(JDK14)

一 类图
在这里插入图片描述
实现了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[]。

为什么会这

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值