类的构造函数默认构造函数

📅 2026/7/1 8:11:37
类的构造函数默认构造函数
public CopyOnWriteArrayList() { // 设置数组 setArray(new Object[0]); }CopyOnWriteArrayList(Collection? extends E)javapublic CopyOnWriteArrayList(Collection? extends E c) { Object[] elements; if (c.getClass() CopyOnWriteArrayList.class) // 类型相同 // 获取c集合的数组 elements ((CopyOnWriteArrayList?)c).getArray(); else { // 类型不相同 // 将c集合转化为数组并赋值给elements elements c.toArray(); // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elements.getClass() ! Object[].class) // elements类型不为Object[]类型 // 将elements数组转化为Object[]类型的数组 elements Arrays.copyOf(elements, elements.length, Object[].class); } // 设置数组 setArray(elements); }该构造函数的处理流程如下判断传入的集合c的类型是否为CopyOnWriteArrayList类型若是则获取该集合类型的底层数组(Object[])并且设置当前CopyOnWriteArrayList的数组(Object[]数组)进入步骤③否则进入步骤②将传入的集合转化为数组elements判断elements的类型是否为Object[]类型(toArray方法可能不会返回Object类型的数组)若不是则将elements转化为Object类型的数组。进入步骤③设置当前CopyOnWriteArrayList的Object[]为elements。CopyOnWriteArrayList(E[])该构造函数用于创建一个保存给定数组的副本的列表。javapublic CopyOnWriteArrayList(E[] toCopyIn) { // 将toCopyIn转化为Object[]类型数组然后设置当前数组 setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class)); }核心函数分析对于CopyOnWriteArrayList的函数分析主要明白Arrays.copyOf方法即可理解CopyOnWriteArrayList其他函数的意义。copyOf函数该函数用于复制指定的数组截取或用 null 填充(如有必要)以使副本具有指定的长度。javapublic static T,U T[] copyOf(U[] original, int newLength, Class? extends T[] newType) { SuppressWarnings(unchecked) // 确定copy的类型(将newType转化为Object类型将Object[].class转化为Object类型 // 判断两者是否相等若相等则生成指定长度的Object数组 // 否则,生成指定长度的新类型的数组) T[] copy ((Object)newType (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); // 将original数组从下标0开始复制长度为(original.length和newLength的较小者),复制到copy数组中(也从下标0开始) System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }add函数javapublic boolean add(E e) { // 可重入锁 final ReentrantLock lock this.lock; // 获取锁 lock.lock(); try { // 元素数组 Object[] elements getArray(); // 数组长度 int len elements.length; // 复制数组 Object[] newElements Arrays.copyOf(elements, len 1); // 存放元素e newElements[len] e; // 设置数组 setArray(newElements); return true; } finally { // 释放锁 lock.unlock(); } }此函数用于将指定元素添加到此列表的尾部处理流程如下获取锁(保证多线程的安全访问)获取当前的Object数组获取Object数组的长度为length进入步骤②。根据Object数组复制一个长度为length1的Object数组为newElements(此时newElements[length]为null)进入下一步骤。将下标为length的数组元素newElements[length]设置为元素e再设置当前Object[]为newElements释放锁返回。这样就完成了元素的添加。addIfAbsent方法该函数用于添加元素(如果数组中不存在则添加否则不添加直接返回)可以保证多线程环境下不会重复添加元素。javaprivate boolean addIfAbsent(E e, Object[] snapshot) { // 重入锁 final ReentrantLock lock this.lock; // 获取锁 lock.lock(); try { // 获取数组 Object[] current getArray(); // 数组长度 int len current.length; if (snapshot ! current) { // 快照不等于当前数组对数组进行了修改 // Optimize for lost race to another addXXX operation // 取较小者 int common Math.min(snapshot.length, len); for (int i 0; i common; i) // 遍历 if (current[i] ! snapshot[i] eq(e, current[i])) // 当前数组的元素与快照的元素不相等并且e与当前元素相等 // 表示在snapshot与current之间修改了数组并且设置了数组某一元素为e已经存在 // 返回 return false; if (indexOf(e, current, common, len) 0) // 在当前数组中找到e元素 // 返回 return false; } // 复制数组 Object[] newElements Arrays.copyOf(current, len 1); // 对数组len索引的元素赋值为e newElements[len] e; // 设置数组 setArray(newElements); return true; } finally { // 释放锁 lock.unlock(); } }该函数的流程如下:获取锁获取当前数组为currentcurrent长度为len判断数组之前的快照snapshot是否等于当前数组current若不相等则进入步骤2否则进入步骤4不相等表示在snapshot与current之间对数组进行了修改(如进行了add、set、remove等操作)获取长度(snapshot与current之间的较小者)对current进行遍历操作若遍历过程发现snapshot与current的元素不相等并且current的元素与指定元素相等(可能进行了set操作)进入步骤5否则进入步骤3在当前数组中索引指定元素若能够找到进入步骤5否则进入步骤4复制当前数组current为newElements长度为len1此时newElements[len]为null。再设置newElements[len]为指定元素e再设置数组进入步骤5释放锁返回。set函数此函数用于用指定的元素替代此列表指定位置上的元素也是基于数组的复制来实现的。javapublic E set(int index, E element) { // 可重入锁 final ReentrantLock lock this.lock; // 获取锁 lock.lock(); try { // 获取数组 Object[] elements getArray(); // 获取index索引的元素 E oldValue get(elements, index); if (oldValue ! element) { // 旧值等于element // 数组长度 int len elements.length; // 复制数组 Object[] newElements Arrays.copyOf(elements, len); // 重新赋值index索引的值 newElements[index] element; // 设置数组 setArray(newElements); } else { // Not quite a no-op; ensures volatile write semantics // 设置数组 setArray(elements); } // 返回旧值 return oldValue; } finally { // 释放锁 lock.unlock(); } }remove函数此函数用于移除此列表指定位置上的元素。javapublic E remove(int index) { // 可重入锁 final ReentrantLock lock this.lock; // 获取锁 lock.lock(); try { // 获取数组 Object[] elements getArray(); // 数组长度 int len elements.length; // 获取旧值 E oldValue get(elements, index); // 需要移动的元素个数 int numMoved len - index - 1; if (numMoved 0) // 移动个数为0 // 复制后设置数组 setArray(Arrays.copyOf(elements, len - 1)); else { // 移动个数不为0 // 新生数组 Object[] newElements new Object[len - 1]; // 复制index索引之前的元素 System.arraycopy(elements, 0, newElements, 0, index); // 复制index索引之后的元素 System.arraycopy(elements, index 1, newElements, index, numMoved); // 设置索引 setArray(newElements); } // 返回旧值 return oldValue; } finally { // 释放锁 lock.unlock(); } }