2014-01-23 21 views
5

Collection类是2 toArray()方法:<T> T[] toArray(T[] a)Object[] toArray()。没有E[] toArray()方法。为什么? 它与类型擦除相关,但有例如方法 - boolean add(E e)。为什么可以创建参数化的add,并且不可能创建toArray()方法?toArray()方法Collection类中的

+0

对反引号很满意吗? – csmckelvey

+0

你能解释一下吗?反拨有什么问题:p? – Pawel

+0

没什么错,我只是给你一个难过的时间:)在这么小的空间里看到这么多东西真是难得。 – csmckelvey

回答

11

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

有没有办法,它可以实际上创建E[]在执行时,因为它不知道阵列创建,由于类型擦除类型。

add方法真的接受任何东西,但是编译器只检查参数类型与E第一兼容。执行时不需要知道什么。同样,对于像List.get,编译器插入一个撒入调用代码:

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

被编译成相同的代码,因为这预泛型代码:

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]会通过,将有编译,但后来我们不得不当toArray试图将String(唯一元素)投射到Integer时,获得ClassCastException

+0

我正确吗?很快:'add'方法可以通过编译器检查,所以可以有参数化类型。 'toArray'方法也可以由编译器进行检查,但它什么也不给,因为由于类型擦除返回的类型将始终是Object的数组?它可以创建,但它是没用的。参数化类型在'add'方法中,因为编译器可以检查参数并且它是有用的。 – Pawel

+0

@Pawel:排序。这真的与可以检查的内容有关,*当*时。我不*很确定我完全按照你的想法,但希望他们符合答案:) –

相关问题