Collection类中的toArray()方法

Paw*_*wel 5 java generics collections

Collection课堂上有两种toArray()方法:<T> T[] toArray(T[] a)Object[] toArray().没有E[] toArray()方法.为什么?它与类型擦除有关,但有例如方法 - boolean add(E e).为什么可以创建参数化add,并且无法创建toArray()方法?

Jon*_*eet 11

没有E [] toArray()方法.为什么?

由于类型擦除,它无法实际创建E[]执行时,因为它不知道要创建的数组类型.

add方法将真正接受任何东西,但编译器只是检查参数类型是否与E第一个兼容.在执行时不需要知道任何事情.同样,对于类似的东西List.get,编译器将一个强制转换插入到调用代码中:

List<String> strings = new ArrayList<>();
strings.add("hello");
String first = strings.get(0);
Run Code Online (Sandbox Code Playgroud)

编译为与此pre-generics代码相同的代码:

List strings = new ArrayList();
strings.add("hello");
String first = (String) strings.get(0);
Run Code Online (Sandbox Code Playgroud)

现在这很好,因为我们知道String调用代码执行时的类型......但是toArray(),创建数组的代码需要知道类型...而类型擦除意味着它实际上并不知道.传入的数组toArray()允许它创建相同类型的数组.实际上,创建的对象的实际类型可以显示为依赖于您传入的数组:

import java.util.*;

public class Test {

    public static void main(String[] args) {
        List<Object> objects = new ArrayList<Object>();
        objects.add("xyz");

        Object[] array1 = objects.toArray(new String[0]);
        Object[] array2 = objects.toArray(new Object[0]);
        System.out.println(array1.getClass()); // class [Ljava.lang.String;
        System.out.println(array2.getClass()); // class [Ljava.lang.Object;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我们想通过new Integer[0]它会编译,但随后我们就已经得到了ClassCastExceptiontoArray试图施放String(唯一元素)到Integer.