成员

构造器

public ArrayList(Collection<? extends E> c)

  1. public ArrayList(Collection<? extends E> c) {
  2. elementData = c.toArray(); //~ c 也是一个集合, c.toArray() 是一个 Object[] 数组
  3. if ((size = elementData.length) != 0) { //~ 非空
  4. // c.toArray might (incorrectly) not return Object[] (see 6260652)
  5. if (elementData.getClass() != Object[].class)
  6. elementData = Arrays.copyOf(elementData, size, Object[].class);
  7. } else {
  8. // replace with empty array.
  9. this.elementData = EMPTY_ELEMENTDATA; //~ 如果是空数组则引用 EMPTY_ELEMENTDATA
  10. }
  11. }

这里有一个有意思的点是 line2, 首先, c 是一个集合, c.toArray() 是一个数组, 在 Collection 这个接口中规定了 toArray() 这个方法返回的是 Object[] 数组, 而实现接口并重写方法有两种情况:

  1. 实现类返回值不变, 还是 Object[] 数组;
  2. 实现类返回值改变, 比如改成 String[] 数组;

而根据数组引用这一篇文章, 我们知道, 数组可以引用其元素类型子类的数组对象(相当于数组的多态), 而 Object 又是所有类的父类, 所以上面两种情况在这个构造器的 line2 都看上去没有问题, 我们举两个例子:

@Test
public void test() {
    Object[] objs1 = new MyArrayList1().toArray(); // 正常引用
    System.out.println(objs1.getClass()); // class [Ljava.lang.String;

    Object[] objs2 = new MyArrayList1().toArray(); // 正常引用
    System.out.println(objs2.getClass()); // class [Ljava.lang.String;
}

class MyArrayList1 extends ArrayList{
    @Override
    public Object[] toArray() {
        return new String[]{"1", "2", "3"};
    }
}

class MyArrayList2 extends ArrayList{
    @Override
    public String[] toArray() {
        return new String[]{"1", "2", "3"};
    }
}

可以发现构造器的 line2 引用没问题, 但是有一个问题是, 在上面代码块的 Object[] objs1Object[] objs2 的类型都变成了 class [Ljava.lang.String , 也就是说, 现在, obj1 和 obj2 都只能存放字符串(或其子类, 当然, 字符串没有子类)了:

objs1[0] = new Son(); // java.lang.ArrayStoreException
objs2[1] = new Father(); // java.lang.ArrayStoreException

这就是大 Bug 了, 好好的 Object[] 数组怎么就功能锐减了, 这不行, 所以源码才说:

c.toArray might (incorrectly) not return Object[] (see 6260652)

并进行了判断, 如果为空则引用其内的静态空数组, 如果非空, 判断其数组类型是不是 Object[], 不是的话调用 Arrays.copyOf() 浅拷贝一个 Object[] 数组, 这样就可以存储任何类型的数据了.

看了下 JDK11 仍然是这样的写法, 所以说这只能说是 Java 本身的机制问题了.

问题

modCount:
https://www.cnblogs.com/zuochengsi-9/p/7050351.html

grow():
大整数 * 1.5 变负数.