【问题标题】:Java Class Cast Exception when creating Generic Array创建通用数组时出现 Java 类强制转换异常
【发布时间】:2014-01-26 01:14:34
【问题描述】:

我正在尝试编写一个必须泛化为 Comparable 的 PriorityQueue。这是构造函数:

public class DavidiArrayPriorityQueue <E extends Comparable<E>> implements PriorityQueue<E> {

    private E data[];
    private int numElements;

    //creates an empty priority queue with 10 spaces by default
    public DavidiArrayPriorityQueue(){

        data= (E[]) new Object[20];
        numElements=0;
    }

当我用

初始化它时
DavidiArrayPriorityQueue<Integer> test=new DavidiArrayPriorityQueue<Integer>();

它抛出 [Ljava.lang.Object;不能转换为 [Ljava.lang.Comparable;

【问题讨论】:

  • 确实; Object 不是 Comparable
  • 也许你应该使用列表而不是数组?
  • @OliCharlesworth:或者,更重要的是:Object[] 不是Comparable[]

标签: java arrays generics


【解决方案1】:

数组的元素类型实际上是数组的一部分,在运行时是已知的。因此,当您编写new Object[] 时,您正在创建一个元素类型为Object 的数组,即使您的意图是数组的元素都将始终具有类型(例如)Comparable,您仍然不能将其转换为Comparable[]

在您的情况下,您将其转换为 E[]。由于擦除,无法在运行时完全强制强制转换,因此将其降级为 Comparable[] 的强制转换;因此,从技术上讲,您可以通过编写(E[]) new Comparable[] 来欺骗编译器允许这样做。但这是个坏主意,因为这样你就有了一个E[] 类型的数组表达式,它的元素类型实际上不是E。您已经绕过了类型系统,这可能会在以后导致令人困惑的错误。

最好让data 的类型为Object[](或者可能是Comparable&lt;?&gt;[]),并对E 执行必要的强制转换。这将导致编译器警告,因为编译器也无法检查这些转换,但至少您可以验证您的代码是否正确并正确保留类型系统(然后使用注释抑制警告) .

【讨论】:

  • new Comparable&lt;?&gt;[] 转换为 E[] 应该没问题,只要数组没有暴露在类之外(它可能被分配给可具体化的类型)。
  • @PaulBellora,这种情况出现在 Collections 框架的类中 java.util
  • 喜欢Vector。这里 Object[] 用于存储和获取元素,使用类型转换。
  • @ambigram_maker 明白了。是的,这也很好,除了可能有更多未经检查的警告要压制。
  • 很高兴我能帮上忙。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多