在泛型类型“T”的对象和泛型类型的对象之间进行转换“<t extends =”“可比较<t =”“>&gt;”</t>

时间:2013-08-26 23:51:02

标签: java generics inheritance comparable

我已按以下方式实现了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。

提前致谢。

1 个答案:

答案 0 :(得分:3)

根据例外情况,您似乎正在使用element初始化new Object[someLength]并对T[]进行未经检查的转换。这可能发生在ArrayLinearList。问题是在这段代码中:

element[ pedro ] = maria;

element在运行时被视为Comparable[],而Object[]不是Comparable[]

有很多与泛型数组创建相关的现有帖子,但是你的问题很有趣,因为你已经将继承抛入混合中(缩小了类型参数的界限)。最佳解决方案似乎只与element类中的ArrayLinearList进行交互。设为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;
    }
}

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

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

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

但这是一个非常糟糕的解决方案,可以阻止基础问题。