java数组泛型初始化

时间:2014-03-03 20:36:52

标签: java arrays exception generics casting

此代码正常工作并打印出数字120.但是,如果我取消注释主函数中的行。

代码抛出异常:线程中的异常" main" java.lang.ClassCastException:[Ljava.lang.Comparable;无法转换为[Ljava.lang.Double;     在General.main

我搜索并发现了几个关于java中泛型数组的讨论。人们承认在Java中对泛型数组的处理不是很好。但是我对这段代码仍然感觉非常糟糕:在不同的地方打印出一行会产生不同的后果,(正确执行与抛出异常)。

有人可以对此代码发表评论,并建议是否对主函数中与println代码相关的异常有任何简单的修复?

这是我的代码:

public class General<Key extends Comparable<Key>> {
    public Key[] keys;      
    @SuppressWarnings("unchecked")
    public General(int NMAX) {
        keys = (Key[]) new Comparable[NMAX];
        System.out.println(keys.length);
    }
    public static void main(String[] args){
    General<Double> g = new General<Double>(120);
    //      System.out.println(g.keys.length);
    }
}


System.out.println(g.keys.length);

2 个答案:

答案 0 :(得分:2)

你在一个看似奇怪的地方得到例外的原因是因为擦除。删除KeyComparable,因此此处的演员实际上从未在运行时发生:

keys = (Key[]) new Comparable[NMAX];

但是正如您所观察到的,当您从对象外部检索数组时,会发生强制转换。 Comparable[]不是Double[],因此您获得例外。只要您不在课外访问数组,您执行此操作的方式可能不会导致问题。

“更安全”的习惯是通过使其声明为Comparable[]来使数组非泛型。然后你:

  • 确保只能将Key放入数组中。
  • 在检索调用中进行未经检查的强制转换。

这样的事情:

@SuppressWarnings("rawtypes")
public class General<Key extends Comparable<Key>> {
    private Comparable[] keys;

    public General(int NMAX) {
        keys = new Comparable[NMAX];
    }

    public void set(int ind, Key k) {
        keys[ind] = k;
    }

    @SuppressWarnings("unchecked")
    public Key get(int ind) {
        return (Key)keys[ind];
    }
}

这是类型安全的,它是JDK的方式。

另一种方法是让客户端提供数组:

public class General<Key extends Comparable<Key>> {
    private Key[] keys;

    public General(Key[] keys) {
        this.keys = keys;
    }
}

您还应该考虑使用List,因为它们会为您完成所有这些操作并且完全通用。你可以new ArrayList<Key>()

答案 1 :(得分:1)

您可以尝试将密钥保存为Comparable []数组。

public class General<Key extends Comparable<Key>> {
public Comparable[] keys;      // keys[i] = priority of i

public General(int NMAX) {
    keys = new Comparable[NMAX];
    System.out.println(keys.length);
}

public static void main(String[] args) {
    General<Double> g = new General<Double>(120);
    System.out.println(g.keys.length);
}
}