Java泛型未选中ArrayList数组数组的转换警告

时间:2014-01-10 18:41:32

标签: java generics

我正在尝试为3个ArrayLists定义一个数组,每个数组包含一个double数组。我使用了以下语法:

ArrayList<double[]> testSamples[] = new ArrayList[] {
    new ArrayList<double[]>(), new ArrayList<double[]>(), new ArrayList<double[]>()
};

但是,当我编译代码时,这会生成“警告:[未选中]未经检查的转换”警告。 注意:代码正常,我只是试图修正我的语法(正确)来解决警告。由于代码有效,它似乎得到了Java的支持,我很困惑为什么我不能编写类似的东西(这会产生编译错误):

ArrayList<double[]> testSamples[] = new ArrayList<double[]>[] {
        new ArrayList<double[]>(), new ArrayList<double[]>(), new ArrayList<double[]>()
};

我做错了什么?

2 个答案:

答案 0 :(得分:4)

您隐式地从原始类型ArrayList的数组转换为ArrayList<double[]>的数组。总而言之,你不应该做这样的事情。如果你知道你将有3个列表,那么你可以创建一个类来代替它们:

class Container {
    private ArrayList<double[]> list1;
    private ArrayList<double[]> list2;
    private ArrayList<double[]> list3;

    ...  // constructors and whatnot

    public ArrayList<double[]> getList(int i) {  // analog of testSamples[i]
        switch (i) {
        case 0:
            return list1;
        case 1:
            return list2;
        case 2:
            return list3;
        default:
            throw new IllegalArgumentException();
        }
    }
}

如果列表数量未固定为3,那么您可以使用List<ArrayList<double[]>>代替。

答案 1 :(得分:1)

这是创建参数化类型数组的常见问题。为什么你不能使用new创建一个参数化类型的数组是一个很长时间的主题,这里已经多次介绍过;它基本上与数组如何对元素类型执行运行时检查有关,但运行时检查不能检查类型参数。

长话短说,某种未经检查的警告是不可避免的(因为它确实可能使其违反阵列类型的保证)。如果你不介意“不安全”,那么写它的最犹豫的方法是使用通配类型而不是原始类型创建数组,并将其转换为正确类型的数组(是的,这是一个未经检查的转换):

ArrayList<double[]>[] testSamples =
    (ArrayList<double[]>[]) new ArrayList<?>[] { ... }
相关问题