java数组泛型初始化

java数组泛型初始化,java,arrays,exception,generics,casting,Java,Arrays,Exception,Generics,Casting,此代码工作正常,并打印出编号120。但是,如果我取消注释main函数中的行 代码正在引发异常:线程“main”java.lang.ClassCastException中的异常:[Ljava.lang.Comparable;无法转换为[Ljava.lang.Double; 梅因将军 我搜索并发现了一些关于java中泛型数组的讨论。人们承认java中对泛型数组的处理不是很好。但我仍然对这段代码感到非常不好:在不同的地方打印一行将产生不同的结果(正确执行与抛出异常) 是否有人可以对这段代码发表评论,并

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

代码正在引发异常:线程“main”java.lang.ClassCastException中的异常:[Ljava.lang.Comparable;无法转换为[Ljava.lang.Double; 梅因将军

我搜索并发现了一些关于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);
公共类通用{
公钥[]密钥;
@抑制警告(“未选中”)
公共通用(int NMAX){
键=(键[])新的可比[NMAX];
System.out.println(键.长度);
}
公共静态void main(字符串[]args){
一般g=新的一般(120);
//系统输出打印长度(g键长度);
}
}
系统输出打印长度(g键长度);

您可以尝试将键保留为可比较的[]数组

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);
}
}
公共类通用{
公共可比较[]密钥;//密钥[i]=i的优先级
公共通用(int NMAX){
键=新的可比[NMAX];
System.out.println(键.长度);
}
公共静态void main(字符串[]args){
一般g=新的一般(120);
系统输出打印长度(g键长度);
}
}

在一个看似奇怪的地方出现异常的原因是因为擦除。
的擦除是
可比的
,因此这里的强制转换实际上从未在运行时发生:

keys = (Key[]) new Comparable[NMAX];
但正如您所观察到的,当您从对象外部检索数组时,确实会发生强制转换。
Comparable[]
不是
Double[]
,因此您会遇到异常。只要您不在类外部访问数组,您这样做可能不会导致问题

“更安全”的习惯用法是通过将数组的声明设置为可比较[],使其非泛型

  • 确保只能将
    放入数组中
  • 对检索调用进行未选中的强制转换
大概是这样的:

@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];
    }
}
@SuppressWarnings(“rawtypes”)
公共课普通{
私钥;
公共通用(int NMAX){
键=新的可比[NMAX];
}
公共无效集(int ind,键k){
键[ind]=k;
}
@抑制警告(“未选中”)
公钥get(int ind){
返回(键)键[ind];
}
}
这是类型安全的,JDK就是这样做的

另一种方法是让客户端提供阵列:

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

    public General(Key[] keys) {
        this.keys = keys;
    }
}
公共类通用{
私钥[]密钥;
通用公共密钥(密钥[]密钥){
this.keys=keys;
}
}

你也应该考虑使用一个列表,因为它们为你做了所有的事情,而且是完全通用的。你可以做<代码>新的ARAYLISH()/Cux>。-然后你可以使类

通用
@Elliott的查询非常合理。简短的回答是示例代码段的类型不太安全。列表会帮你解决这个问题。ArrayList肯定会解决问题,但我希望更深入地理解我的方法失败的原因,正如下面的人所解释的。谢谢这里有很多需要澄清的地方。我在学习SedgeWick教授的算法课程,尽量不使用复杂的泛型来实现简单的东西