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]它会编译,但随后我们就已经得到了ClassCastException当toArray试图施放String(唯一元素)到Integer.