Collection类中的toArray()方法

时间:2014-01-23 19:25:42

标签: java generics collections

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

1 个答案:

答案 0 :(得分:11)

  

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

在执行时实际创建E[]是不可能的,因为它不会因为类型擦除而知道要创建的数组的类型

add方法确实接受任何内容,但编译器只是先检查参数类型是否与E兼容。在执行时不需要知道任何事情。同样,对于类似List.get的内容,编译器会在调用代码中插入强制转换:

List<String> strings = new ArrayList<>();
strings.add("hello");
String first = strings.get(0);

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

List strings = new ArrayList();
strings.add("hello");
String first = (String) strings.get(0);

现在这很好,因为我们在调用代码的执行时知道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;
    }
}

如果我们传入new Integer[0],则会编译,但是当ClassCastException尝试时我们已经获得了toArrayString(唯一元素)转换为Integer