ArrayList 带参数(Collection<? extends E> c)构造器的一点见解

来源:互联网 发布:vc6.0连接sql数据库 编辑:程序博客网 时间:2024/06/05 16:47

先贴上源码:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
 
    private static final Object[] EMPTY_ELEMENTDATA = {};


    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    transient Object[] elementData; // non-private to simplify nested class access
    ...............................................

    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)

   // Arrays.asList卻不是這樣,如果它的類型是一個Object[]子類(比如String[]),那麼toArray()就會返回這個子類而不是Object[]
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

    ..........................................

}


关于Arrays.asList()
public class Arrays {  
    
private static class ArrayList<E> extends AbstractList<E>
        implements RandomAccess, java.io.Serializable
    {
        private static final long serialVersionUID = -2764017481108945198L;
        private final E[] a;


        ArrayList(E[] array) {
            a = Objects.requireNonNull(array);
        }


@Override
  public int size() {
return a.length;
         }


        @Override
        public Object[] toArray() {
            return a.clone();
        }

}

Arrays.asList()返回一个内部类,调用内部类的toArray()方法返回的不是一个Object[],而是E[]。


 if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);

ArrayList构造器的源码 elementData.getClass()一旦不是一个Object[]就会将他复制成为一个Object[],为什么还要做这样一种转换?

String b[] = {"a","b"};
Object a[] = b;

向上转型是允许的,但是

String b[] = {"a","b"};
Object a[] = b;
a[0] = 1;

Exception in thread "main" java.lang.ArrayStoreException: java.lang.Integer 运行时抛出这个异常。

意味着如果不转成Object[],你想某个位置add一个Object的子类时,这个时候就会出现以上的异常。






阅读全文
0 0
原创粉丝点击