0

我通过以下方式实现了一个 ArrayLinearList 类

public class ArrayLinearList<T> implements LinearList<T>, Iterable<T>

其中包含类成员

protected T[] element

为了扩展类的功能,我创建了一个继承自第一个类的新类

class SuperList<T extends Comparable<T>> extends ArrayLinearList<T>

这里我确保类型 T 实现了 Comparable 接口(这是不能更改的)。

在 SuperList 类中,我有以下方法

public void replace( int pedro, T maria ){
   element[ pedro ] = maria;

}

该方法的行生成以下错误

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;

但是,如果我以以下方式声明类,我就不再有这个问题了(但是这样我就不再能够比较类对象了)

class SuperList<T> extends ArrayLinearList<T>{

对于解决此问题的任何帮助,我将不胜感激。我不允许修改类\ [ ArrayLinearList,只能修改类SuperList。

提前致谢。

4

1 回答 1

3

根据异常,您似乎正在初始化elementnew Object[someLength]执行未经检查的强制转换为T[]. 这很可能发生在ArrayLinearList. 问题是在这段代码中:

element[ pedro ] = maria;

element在运行时被视为 a Comparable[],而 anObject[]不是Comparable[].

有许多与泛型数组创建相关的现有帖子,但您的问题很有趣,因为您已经将继承混入其中(缩小了类型参数的范围)。最好的解决方案似乎只elementArrayLinearList课堂内进行互动。制作它private并暴露 getter 和 setter。这应该避免像这样的运行时失败(在进行未经检查的强制转换时需要考虑避免(T[])new Object[someLength])。

例如:

public class ArrayLinearList<T> implements LinearList<T>, Iterable<T> {

    private final T[] elements;

    public ArrayLinearList(final int length) {
        @SuppressWarnings("unchecked") // won't be exposed outside this class
        final T[] withNarrowedType = (T[])new Object[length];
        elements = withNarrowedType;
    }

    public final void set(final int index, final T element) {
        elements[index] = element;
    }
}

编辑:我刚刚注意到你的免责声明“我不允许只修改ArrayLinearListSuperList。” 那很不幸,因为作者ArrayLinearList编写了类型不安全的代码。但是问题变成了为什么像这样的方法SuperList.replace需要直接与数组交互(或根本存在)。看起来它只是将一个新元素分配给指定的索引 - 有没有ArrayLinearList可以使用的方法来做到这一点?

如果一切都失败了,这是最后的解决方法:

((Object[])element)[pedro] = maria;

但这是一个糟糕的解决方案,用胶带解决了根本问题。

于 2013-08-27T00:17:18.180 回答