ArrayList源码学习
成员变量解读
1. serialVersionUID
成员变量:
-
代码
/** * 这个UID主要是为了在ArrayList序列化的时候判断属性是否合格产生的<br/> * https://www.jianshu.com/p/91fa3d2ac892关于UID的详情可看这里,通俗易懂 * 有点类似于版本控制的变量 * * @author Hue Fu * @date 2021-01-31 10:42 * @since 0.0.1 */ private static final long serialVersionUID = 8683452581122892189L;
-
解读
-
- 简单来说就是序列化和反序列化时候的标识符。在开发的时候我们一般用它来控制版本的兼容性,如果版本中这个对象的成员变量改变了,为了版本的向后兼容,或者不想让以前的版本来兼容它,就可以改变UID的值抛出一个InvalidClassExceptions异常。
-
序列化和反序列化有什么作用呢?
-
将对象编译为字节流数组,然后可以从jvm堆内存保存到共享内存中,从而可以保存到存储介质中去(磁盘)
-
网络传输,在传输的时候我们传输的都是字节流或者xml,序列化可以实现这个
-
序列化保存的是对象的状态,而不是类的状态,所以静态变量的内容和translate关键词修饰的变量没法序列化保存。
-
-
序列化的方式除了Serializable接口,还有什么呢?他们有什么区别呢
TODO
-
2. DEFAULT_CAPACITY
:默认容量
-
代码
/** * 默认的初始化容量<br/> * Default initial capacity. * * @author Hue Fu * @date 2021-01-31 10:43 * @since 0.0.1 */ private static final int DEFAULT_CAPACITY = 10;
-
解读
- 定义了一个默认的初始化容量,在
ensureCapacity
方法中被调用,这个方法最常被add方法给调用。
- 定义了一个默认的初始化容量,在
3. EMPTY_ELEMENTDATA
:空元素数据数组
-
代码
/** * Shared empty array instance used for empty instances.<br/> * 它就是个空数组实例,空的数组 * @author Hue Fu * @date 2021-01-31 19:18 * @since 0.0.1 */ private static final Object[] EMPTY_ELEMENTDATA = {};
-
解读
- 这就是一个空数组罢了
4. DEFAULTCAPACITY_EMPTY_ELEMENTDATA
:默认容量空元素数据数组
-
代码
/** * ArrayList无参构造函数,构造的就是这个默认容量的空数组。<br/> * 用于默认的空数组实例对象构建,和EMPTY_ELEMENTDATA不一样<br/> * Shared empty array instance used for default sized empty instances. We<br/> * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when<br/> * first element is added. * * @author Hue Fu * @date 2021-01-31 19:21 * @since 0.0.1 */ private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
-
解读
- 这是无参构造函数时赋值的底层数组
5. elementData
:ArrayList的底层数组,几乎所有的方法都是对这玩意进行操作的
-
代码
/** * ArrayList的底层数组实现就是通过这个任意类型的数组<br/> * transient关键字的作用是:阻止序列化对象中的不必要成员变量持久化<br/> * https://www.cnblogs.com/lanxuezaipiao/p/3369962.html细节可查阅这个<br/> * non-private to simplify nested class access,不声明为私有的原因是方便内部类调用<br/> * * 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. * * @author Hue Fu * @date 2021-01-31 11:25 * @since 0.0.1 */ transient Object[] elementData; // non-private to simplify nested class access
-
解读
- 这玩意就是ArrayList的底层基础啊,所有的方法操作都是对它进行的。
6. size
:数组中包含的元素数量,不是数组的长度。元素数量和数组长度概念一定要分清楚。
-
代码
/** * 注意这里的size表示的是数组中的元素数量,null元素和空元素可是不一样的呦,如果一个<br/> * 元素被标记为null那么它也是占有一个空间大小的,也就是说null元素也会占用一个size大小<br/> * The size of the ArrayList (the number of elements it contains). * * @serial * * @author Hue Fu * @date 2021-01-31 11:27 * @since 0.0.1 */ private int size;
-
解读
- 这个变量一直存放着当前数组中的元素总个数呢。
构造方法解读
1. 无参构造
-
代码
/** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
-
解读
-
this.elementData
:是ArrayList操作的底层数组。 -
DEFAULTCAPACITY_EMPTY_ELEMENTDATA
:静态创建的一个final空数组。成员变量部分有介绍。
-
2. 单参构造-初始化数组大小
-
代码
/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative */ 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的了?
-
创建大于0数组的概率大啊
-
写代码的时候很少是需要创建一个长度为0的数组的,再不济也是空参啊,没事儿传个0干啥,脱裤子放屁--多此一举。但是作为程序员这种情况也是要考虑到的。
-
如果传入的是一个<0的数字,那么最后会抛出一个非法操作的异常,说你传入的初始容量是不正确的。
-
-
3. 单参构造-传个继承了Collection接口实现的对象
-
代码
/** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ public ArrayList(Collection<? extends E> c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { elementData = a; } else { elementData = Arrays.copyOf(a, size, Object[].class); } } else { // replace with empty array. elementData = EMPTY_ELEMENTDATA; } }
-
解读
- 传入的是一个实现了继承
Collection
接口的实体类,比如:Set
,List
的实体类
- 传入的是一个实现了继承
网友评论