zoukankan      html  css  js  c++  java
  • c.toArray might not return Object[]?

    看源码的时候看见这样一句注释:

    c.toArray might not return Object[],在ArrayList构造函数中就是这样一句

    public ArrayList(Collection<? extends E> c) {
            elementData = c.toArray();
            size = elementData.length;
            // c.toArray might (incorrectly) not return Object[] (see 6260652),java的一个bug,在bug文档6260652中。
            if (elementData.getClass() != Object[].class)//虽然elementData 是object[]类型的,但是它指向的类型不一定是Object[],所以还要进行判断。
                elementData = Arrays.copyOf(elementData, size, Object[].class);
    }
    

    就像下面的代码一样

    //通过ArrayList的toArray()传过来的数组一定是Object[]类型的
    List<String> list = new ArrayList<>(Arrays.asList("list"));
    System.out.println(list.getClass());//class java.util.ArrayList
    Object[] listArray = list.toArray();
    System.out.println(listArray.getClass());//class [Ljava.lang.Object;
    listArray[0] = new Object();
    
    //但是构造函数接受的参数是Collection<? extends E> c,其中Arrays.asList()是将数组转换成list集合的一种方法,其满足形参的要求,
    但是其内部的toArray()方法却与ArrayList的不同,其没有保证传递出的数组一定是Object[]类型
    List<String> asList = Arrays.asList("asList"); System.out.println(asList.getClass());//class java.util.Arrays$ArrayList Object[] asListArray = asList.toArray(); System.out.println(asListArray.getClass());//class [Ljava.lang.String; asListArray[0] = new Object();//! java.lang.ArrayStoreException //这样就导致了Object[]的引用指向了String[]的情况,会引起某些问题,如下所示 String[] strings = {new String()}; Object[] objects = strings; objects[0] = new Object();//! java.lang.ArrayStoreException

    再来看看ArrayList的方法和Arrays&ArrayList的方法的不同:

    //ArrayList.class
    public Object[] toArray() {
            return Arrays.copyOf(elementData, size);
        }
    
    //Arrays.class
    public static <T> T[] copyOf(T[] original, int newLength) {
            return (T[]) copyOf(original, newLength, original.getClass());
        }
    //在一次调用中根据参数的不同,能返回两种类型的数组,当传入的第三个参数为Object[].class的时候,拷贝一份数组将数组类型定为Object[],就像构造方法使用的.当不是Object[]数组拷贝一份原先相同类型的数组返回,可以看到使用了T[].
    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
            T[] copy = ((Object)newType == (Object)Object[].class)
                ? (T[]) new Object[newLength]
                : (T[]) Array.newInstance(newType.getComponentType(), newLength);
            System.arraycopy(original, 0, copy, 0,
                             Math.min(original.length, newLength));
            return copy;
        }
    
    //Arrays.class
    //这里的new ArrayList是Arrays的内部类,不是我们熟知的那个
    public static <T> List<T> asList(T... a) {
            return new ArrayList<>(a);
        }
    //Arrays$ArrayList
    private final E[] a;//泛型数组
    
    public Object[] toArray() {
                return a.clone();
            }
    //到这里可以看出若传递给public ArrayList(Collection<? extends E> c)构造函数的集合是Arrays$ArrayList,
    那么它返回的数组类型不一定是Object[],需要在if (elementData.getClass() != Object[].class)进行判断
  • 相关阅读:
    python base64加密文本内容(1)
    python 翻译爬虫
    json为txt文本加密
    python json
    repr()函数
    linux 基本命令
    测试管理工具--禅道
    测试基础理论
    测试用例--场景法
    测试用例--测试大纲(提纲)法
  • 原文地址:https://www.cnblogs.com/liqing-weikeyuan/p/7922306.html
Copyright © 2011-2022 走看看