此代码正常工作并打印出数字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);
答案 0 :(得分:2)
你在一个看似奇怪的地方得到例外的原因是因为擦除。删除Key
为Comparable
,因此此处的演员实际上从未在运行时发生:
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);
}
}