toArray()函数如何确保长类型的列表不能转换为Integer数组

时间:2019-05-30 18:44:01

标签: java generics

    public <T> T[] toArray(T[] a) {
            int size = size();
            if (a.length < size)
                return Arrays.copyOf(this.a, size,
                                     (Class<? extends T[]>) a.getClass());
            System.arraycopy(this.a, 0, a, 0, size);
            if (a.length > size)
                a[size] = null;
            return a;
    }        

    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        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;
    }

无法理解为什么函数copyOf()的第三个参数类型是Class<? extends T[]>而不是Class<T[]>。它们之间的区别是什么?这种限制是否可以确保一种类型的列表不能转换为另一种类型的数组。

2 个答案:

答案 0 :(得分:1)

通配符允许您传递非文字类。

例如:

copyOf(new String[0], 0, String[].class);
copyOf(new String[0], 0, new String[0].getClass());

当第三个参数类型为Class<? extends T[]>时,这两个参数均有效;但只有第一个对Class<T[]>有效。

Ideone demo

实际上,这意味着您可以为编译时不知道的类型调用copyOf;相反,您是从现有数组中获取该类。

答案 1 :(得分:0)

在Java中,数组为covariance

  

在Java中,Integer []是Number []的子类,并且它们都是Object []的子类。这称为协方差。

在您的情况下,这意味着它将接受T的子类型的所有数组作为参数。显然,它比T []更灵活。