当前位置: 首页 > 知识库问答 >
问题:

为什么我得到一个类强制转换异常(与泛型,可比)?

寿子轩
2023-03-14

我试图实现一个排序和未排序的数组列表。两者都扩展了一个名为AbstractArrayMyList的类,该类包含常见的操作/实现——toString、clear等。。。。

下面是我的AbstractArrayMyList代码(它实现了我定义的通用接口)

public abstract class AbstractArrayMyList<E> implements MyList<E> {
        protected E[] elementData;
       .....
}

我选择对elementData进行保护,以便排序和未排序的专用数组列表可以访问并对其执行操作。这是我对排序数组列表的声明/代码

public class ArrayListSorted<E extends Comparable<E>> extends AbstractArrayMyList<E> 

这一切都很好。然而,当我测试代码时,使用这些行

ArrayListSorted<Integer> toTestInteger = new ArrayListSorted<Integer>()
toTestInteger.insert(0);
assertEquals(toTestInteger.get(0).intValue(), 0);

我得到了班级演员特例

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
    at myarraylist.ArrayListSorted.getIndex(ArrayListSorted.java:38)

发生在这里

@Override
public int getIndex(E value) {
     int lo = 0;
     int hi = size;
     while (lo <= hi) {
         // Key is in a[lo..hi] or not present.
         int mid = lo + (hi - lo) / 2;
         if      (value.compareTo(elementData[mid]) < 0)  hi = mid - 1;

异常与comareTo发生在同一行。有人知道问题是什么吗?我定义了有界通配符,E扩展了可比,这意味着任何希望使用ArrayListSorted的类都必须实现可比接口...

我的意思是我甚至有正确的语法,从http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html,类型扩展类/接口

共有1个答案

阎卓
2023-03-14

问题是您正在使用泛型类型作为数组的类型。数组类型在运行时是具体化的(实际上存在于JVM中),但泛型类型不是。这意味着你的new E[]实际上是一个对象[],而不是你想要的类型的数组。

标准集合通过不提供对数组的直接访问来处理这个问题,并在像get()这样的操作上转换到E。如果您真的认为使用类型化数组是最好的选择,那么您需要通过

protected AbstractArrayMyList(Class<E> clazz) {
    this.elementClass = clazz;
    this.elementData = Array.newInstance(clazz, INITIAL_SIZE);
}

得到ClassCastException的原因是编译器用方法签名的擦除来替换方法签名,这基本上是可接受类型的最大公分母。由于在子类中将EObject缩小为Comparable,因此该方法上的签名最终是Comparable[]而不是Object[]

 类似资料:
  • 问题内容: 我试图实现一个排序和未排序的数组列表。两者都扩展了一个名为AbstractArrayMyList的类,其中包含常见的操作/实现- toString,clear等。 这是我的AbstractArrayMyList代码(它实现了我定义的通用接口) 我选择对elementData进行保护,以便可以对已排序和未排序的专用数组列表进行访问并对其执行操作。这是我的排序数组列表的声明/代码 所有这些

  • 此代码有效。它以“未检查或不安全操作”警告进行编译和运行。 当这两个给我运行时错误时 我遇到的错误如下:

  • 问题内容: 我正在制作一个类,以便模拟C ++中的函数指针的功能。最初,我只用s 做所有事情,但后来我有了一个想法- 为什么不使其真正通用? 问题出在这个构造函数上,该构造函数试图使用签名调用另一个构造函数: 我以为这会很好,但是我收到了以下编译器错误: 因此,我很困惑,我这样做: 现在可以编译,但是我收到以下警告: 我想问题是我不明白这意味着什么。我认为,由于从参数推断出的类型,因此有 必要 调

  • 例外情况: java.lang.ClassCastException:com.interconnect.library.gcm.util.checkplayServices(util.java:96),com.interconnect.library.gcm.regiseter.handleRegister(regiseter.java:53),com.interconnect.library.g

  • 问题内容: 我在一个新项目中将Swift样板代码用于Core Data。我的文件有一个定义的单一实体()和一个属性()。 我有一个看起来像这样的文件: 当我运行它时,它起作用: 我什至可以进入iOS模拟器正在使用的SQLite数据库,并确认已添加该行。 但是,当我运行与上面完全相同的代码,但使用而不是时,出现了与…行关联的错误消息,导致崩溃。如果我继续执行,则每次执行线程1时它都会到达并位于线程1

  • 我有一个启动屏幕,它运行一个从API下载数据的。在该任务的上,我运行下一个来发送存储的电子邮件。完成后,我需要一个弹出一个ok按钮,以便用户知道下载完成。我使用了这个SO问题来尽我所能: AsyncTask内部的Android AlertDialog 现在,当我尝试向对话框添加属性时,我得到一个NullPointerException: <code>生成器上出现错误。setTitle(“销售工具包