Java未选中:为varargs参数未经检查的通用数组创build
我已经设置Netbeans在我的Java代码中显示未经检查的警告,但我无法理解以下几行的错误:
private List<String> cocNumbers; private List<String> vatNumbers; private List<String> ibans; private List<String> banks; ... List<List<String>> combinations = Utils.createCombinations(cocNumbers, vatNumbers, ibans);
得到:
[unchecked] unchecked generic array creation for varargs parameter of type List<String>[]
方法来源:
/** * Returns a list of all possible combinations of the entered array of lists. * * Example: [["A", "B"], ["0", "1", "2"]] * Returns: [["A", "0"], ["A", "1"], ["A", "2"], ["B", "0"], ["B", "1"], ["B", "2"]] * * @param <T> The type parameter * @param elements An array of lists * @return All possible combinations of the entered lists */ public static <T> List<List<T>> createCombinations(List<T>... elements) { List<List<T>> returnLists = new ArrayList<>(); int[] indices = new int[elements.length]; for (int i = 0; i < indices.length; i++) { indices[i] = 0; } returnLists.add(generateCombination(indices, elements)); while (returnLists.size() < countCombinations(elements)) { gotoNextIndex(indices, elements); returnLists.add(generateCombination(indices, elements)); } return returnLists; }
到底什么地方出了问题,我该如何解决这个问题,因为我认为在代码中留下未经检查的警告不是一个好主意?
忘了提及,但我正在使用Java 7。
编辑 :另外我现在看到,该方法有以下几点:
[unchecked] Possible heap pollution from parameterized vararg type List<T> where T is a type-variable: T extends Object declared in method <T>createCombinations(List<T>...)
就像上面提到的janoh.janoh一样,Java中的可变参数只是数组的语法糖,再加上在调用站点上隐式创build数组。 所以
List<List<String>> combinations = Utils.createCombinations(cocNumbers, vatNumbers, ibans);
实际上是
List<List<String>> combinations = Utils.createCombinations(new List<String>[]{cocNumbers, vatNumbers, ibans});
但正如你可能知道的那样, new List<String>[]
在Java中是不允许的,因为在许多其他问题中已经讨论过这个问题,但主要是因为数组在运行时知道它们的组件types,运行时添加的元素是否与其组件types匹配,但对于参数化types,此检查是不可能的。
无论如何,编译器仍然会创build数组,而不是失败。 它做了类似的事情:
List<List<String>> combinations = Utils.createCombinations((List<String>[])new List<?>[]{cocNumbers, vatNumbers, ibans});
这可能是不安全的,但不一定是不安全的。 大多数可变参数方法只是遍历可变参数元素并读取它们。 在这种情况下,它不关心数组的运行时types。 你的方法就是这种情况。 由于您使用的是Java 7,所以您应该将@SafeVarargs
注释添加到您的方法中,并且不会再收到此警告。 这个注解基本上说,这个方法只关心元素的types,而不关心数组的types。
但是,有一些varargs方法可以使用数组的运行时types。 在这种情况下,这可能是不安全的。 这就是为什么警告在那里。
因为java编译器使用隐式数组创build可变参数,并且java不允许创build通用数组(因为types参数是不可修饰的)。
下面的代码是正确的(这个操作是允许的数组),所以未经检查的警告是必要的:
public static <T> List<List<T>> createCombinations(List<T> ... lists) { ((Object[]) lists)[0] = new ArrayList<Integer>(); // place your code here }
在这里看一个全面的解释