美文网首页
ArrayList源码学习--构造方法篇

ArrayList源码学习--构造方法篇

作者: SmileFH | 来源:发表于2021-02-05 09:25 被阅读0次

    ArrayList源码学习

    成员变量解读

    1. serialVersionUID成员变量:
    1. 代码

      /**
           * 这个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;
      
    2. 解读

      1. Java serialVersionUID 有什么作用?

        1. 简单来说就是序列化和反序列化时候的标识符。在开发的时候我们一般用它来控制版本的兼容性,如果版本中这个对象的成员变量改变了,为了版本的向后兼容,或者不想让以前的版本来兼容它,就可以改变UID的值抛出一个InvalidClassExceptions异常。
      2. 序列化和反序列化有什么作用呢?

        1. 将对象编译为字节流数组,然后可以从jvm堆内存保存到共享内存中,从而可以保存到存储介质中去(磁盘)

        2. 网络传输,在传输的时候我们传输的都是字节流或者xml,序列化可以实现这个

        3. 序列化保存的是对象的状态,而不是类的状态,所以静态变量的内容和translate关键词修饰的变量没法序列化保存。

      3. 序列化的方式除了Serializable接口,还有什么呢?他们有什么区别呢

        1. TODO
    2. DEFAULT_CAPACITY:默认容量
    1. 代码

      /**
       * 默认的初始化容量<br/>
       * Default initial capacity.
       *
       * @author Hue Fu
       * @date 2021-01-31 10:43
       * @since 0.0.1
       */
       private static final int DEFAULT_CAPACITY = 10;
      
    2. 解读

      1. 定义了一个默认的初始化容量,在ensureCapacity方法中被调用,这个方法最常被add方法给调用。
    3. EMPTY_ELEMENTDATA:空元素数据数组
    1. 代码

      /**
       * 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 = {};
      
    2. 解读

      1. 这就是一个空数组罢了
    4. DEFAULTCAPACITY_EMPTY_ELEMENTDATA:默认容量空元素数据数组
    1. 代码

      /**
       * 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 = {};
      
    2. 解读

      1. 这是无参构造函数时赋值的底层数组
    5. elementData:ArrayList的底层数组,几乎所有的方法都是对这玩意进行操作的
    1. 代码

      /**
       * 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
      
    2. 解读

      1. 这玩意就是ArrayList的底层基础啊,所有的方法操作都是对它进行的。
    6. size:数组中包含的元素数量,不是数组的长度。元素数量和数组长度概念一定要分清楚。
    1. 代码

      /**
       * 注意这里的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;
      
    2. 解读

      1. 这个变量一直存放着当前数组中的元素总个数呢。

    构造方法解读

    1. 无参构造
    1. 代码

      /**
      * Constructs an empty list with an initial capacity of ten.
      */
      public ArrayList() {
         this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
      }
      
    2. 解读

      1. this.elementData:是ArrayList操作的底层数组。

      2. DEFAULTCAPACITY_EMPTY_ELEMENTDATA:静态创建的一个final空数组。成员变量部分有介绍。

    2. 单参构造-初始化数组大小
    1. 代码

      /**
       * 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);
          }
      }
      
    2. 解读

      1. initialCapacity:指定容量大小

      2. 为啥先判断容量大于0的了?

        1. 创建大于0数组的概率大啊

        2. 写代码的时候很少是需要创建一个长度为0的数组的,再不济也是空参啊,没事儿传个0干啥,脱裤子放屁--多此一举。但是作为程序员这种情况也是要考虑到的。

        3. 如果传入的是一个<0的数字,那么最后会抛出一个非法操作的异常,说你传入的初始容量是不正确的。

    3. 单参构造-传个继承了Collection接口实现的对象
    1. 代码

      /**
       * 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;
          }
      }
      
    2. 解读

      1. 传入的是一个实现了继承Collection接口的实体类,比如:SetList的实体类

    相关文章

      网友评论

          本文标题:ArrayList源码学习--构造方法篇

          本文链接:https://www.haomeiwen.com/subject/oljjtltx.html