Java ClassCastException when eclipse“;固定的;我的代码

Java ClassCastException when eclipse“;固定的;我的代码,java,eclipse,exception,Java,Eclipse,Exception,当eclipse建议我的代码应该是这样时,我得到了一个ClassCastException 我有一个叫科特的班 ArrayList<Kort> kort = new ArrayList<Kort>(); ArrayList kort=new ArrayList(); 然后我使用toArray(),eclipse建议它应该是这样的:Kort[]array=(Kort[])Kort.toArray() 但它给了我一个例外:ClassCastException!:(使用 k

当eclipse建议我的代码应该是这样时,我得到了一个ClassCastException

我有一个叫科特的班

ArrayList<Kort> kort = new ArrayList<Kort>();
ArrayList kort=new ArrayList();
然后我使用
toArray()
,eclipse建议它应该是这样的:
Kort[]array=(Kort[])Kort.toArray()

但它给了我一个例外:ClassCastException!:(

使用

kort.toArray(new Kort[kort.size()]);
使用

您可以做的是:

    Kort[] array = kort.toArray(new Kort[kort.size()]);
这被认为是更好的方法,因为它在数组上保持了类型安全性。如果您不在乎/不想这样做,那么就忽略这个建议。不带参数的toArray()方法返回一个Object[]数组。

您可以做的是:

    Kort[] array = kort.toArray(new Kort[kort.size()]);
这被认为是更好的方法,因为它保持了数组的类型安全性。如果你不在乎/不想这样做,那么就忽略这个建议。不带参数的toArray()方法返回一个Object[]数组。

我的建议是:

kort.toArray(new Kort[0])
从技术上讲,这可能比给出正确的大小稍微慢一点。但是,您不需要两次提到集合变量名,因此出错的可能性更小。它也更易于阅读。另外,它还适用于并发集合,在并发集合中调用
size
实际上没有多大意义

但是,最好的方法是尽可能避免使用引用数组。

我的建议是:

kort.toArray(new Kort[0])
从技术上讲,这可能比给出正确的大小稍微慢一点。但是,您不需要两次提到集合变量名,因此出错的可能性更小。它也更易于阅读。另外,它还适用于并发集合,在并发集合中调用
size
实际上没有多大意义


但是,最好的方法是尽可能避免使用引用数组。

问题的根源在于
java.util.Collection
API中的
Object[]toArray()
Object[]toArray(Object[])
方法之间的差异

第一个表单分配一个大小合适的数组来保存集合的成员,然后将成员引用分配到数组中。由于集合类不知道成员的实际类型(请参见下面的注释),API指定结果是
对象[]的实例
;即,好像是使用
新对象[大小]
分配的

第二种形式采用数组作为参数,该参数将(通常)是存储集合成员引用的位置。因此,程序通过传递所需类型的数组来确定结果的类型。如果提供的数组足够大,可以容纳集合元素,则
toArray
方法将返回提供的数组实例。否则,将使用与提供的数组实例的类型相同。(这可以使用
array以反射方式完成。newInstance(clazz,size)
其中
clazz
是提供的数组的组件类。请注意,type参数不用于执行此操作,并且不能使用。)

所以现在发生的事情是,Eclipse不够聪明,不知道对错误的真正纠正是使用不同的方法重载。为了进行这种纠正,它需要“知道”关于
toArray
方法的两种形式的特定语义。在我看来,这是一个很高的要求

教训是Eclipse建议的更正只是建议…不能保证是正确的修复

注意:集合类不知道要在
toArray()中创建的适当数组类
由于类型擦除而导致的大小写。实现
toArray
的类无法获得有关如何实例化类型的信息。但考虑到通常可以在
集合中插入非
T
的内容(忽略“不安全类型”编译器警告)结果类型是
对象[]
,这可能是一件好事

这个问题早于泛型类型;自从Java1.2中引入集合框架以来,该方法的两种形式就出现了

编辑:在一篇评论中,@Thilo建议,如果Java从一开始就支持泛型,这个问题就不会出现。我的回答是,它不会以这种方式发生,我们不能说如果它们这样做会发生什么。但是我们可以说,如果Java泛型是目前定义的,那么没有你,它是不可能做到这一点的t重新设计集合API


具体而言,泛型类无法确定使用了什么实际类型作为给定实例的类型参数。如果没有此信息,它无法知道要实例化的正确数组类型。在实践中,如果希望泛型类型创建类型参数或某些相关类型的实例,则必须设计API,以便相关方法具有对实际参数类型的
对象的运行时访问权限。例如,实际类对象可以作为构造函数参数提供。

问题的根源是
对象[]toArray()
对象[]toArray(对象[])之间的差异
java.util.Collection
API中的方法

第一个表单分配一个大小合适的数组来保存集合的成员,然后将成员引用分配到数组中。由于集合类不知道成员的实际类型(请参见下面的注释),API指定结果是
对象[]的实例
;即,好像是使用
新对象[大小]
分配的

第二种形式将数组作为参数(通常)存储集合成员引用的位置。因此,程序通过传递所需类型的数组来确定结果的类型。如果提供的数组很大,则