Java unchecked:为 varargs 参数创建未经检查的泛型数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21132692/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java unchecked: unchecked generic array creation for varargs parameter
提问by skiwi
I have set Netbeans to show unchecked warnings in my Java code, but I am failing to understand the error on the following lines:
我已将 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);
Gives:
给出:
[unchecked] unchecked generic array creation for varargs parameter of type List<String>[]
[unchecked] unchecked generic array creation for varargs parameter of type List<String>[]
Method source:
方法来源:
/**
* 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;
}
What is exactly going wrong and how would I fix it, as I suppose leaving unchecked warnings in the code is not a good idea?
到底出了什么问题,我将如何解决它,因为我认为在代码中留下未经检查的警告不是一个好主意?
Forgot to mention, but I am using Java 7.
忘了提,但我使用的是 Java 7。
Edit: Also I see now that the method has the following:
编辑:我现在也看到该方法具有以下内容:
[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>...)
采纳答案by newacct
As janoh.janoh mentioned above, varargs in Java is just a syntactic sugar for arrays plus the implicit creation of an array at the calling site. So
正如 janoh.janoh 上面提到的,Java 中的 varargs 只是数组的语法糖加上在调用站点隐式创建数组。所以
List<List<String>> combinations =
Utils.createCombinations(cocNumbers, vatNumbers, ibans);
is actually
实际上是
List<List<String>> combinations =
Utils.createCombinations(new List<String>[]{cocNumbers, vatNumbers, ibans});
But as you may know, new List<String>[]
is not allowed in Java, for reasons that have been covered in many other questions, but mainly have to do with the fact that arrays know their component type at runtime, and check at runtime whether elements added match its component type, but this check is not possible for parameterized types.
但是您可能知道,new List<String>[]
在 Java 中是不允许的,原因在许多其他问题中已经涵盖,但主要与以下事实有关:数组在运行时知道它们的组件类型,并在运行时检查添加的元素是否与其组件匹配类型,但此检查对于参数化类型是不可能的。
Anyway, rather than failing, the compiler still creates the array. It does something similar to this:
无论如何,编译器不会失败,而是会创建数组。它执行类似的操作:
List<List<String>> combinations =
Utils.createCombinations((List<String>[])new List<?>[]{cocNumbers, vatNumbers, ibans});
This is potentially unsafe, but not necessarily unsafe. Most varargs methods simply iterate over the varargs elements and read them. In this case, it doesn't care about the runtime type of the array. This is the case with your method. Since you are on Java 7, you should add the @SafeVarargs
annotation to your method, and you won't get this warning anymore. This annotation basically says, this method only cares about the types of the elements, not the type of the array.
这可能不安全,但不一定不安全。大多数可变参数方法只是简单地遍历可变参数元素并读取它们。在这种情况下,它不关心数组的运行时类型。你的方法就是这种情况。由于您使用的是 Java 7,您应该将@SafeVarargs
注释添加到您的方法中,您将不会再收到此警告。这个注解基本上是说,这个方法只关心元素的类型,而不关心数组的类型。
However, there are some varargs methods that do use the runtime type of the array. In this case, it is potentially unsafe. That's why the warning is there.
但是,有一些可变参数方法确实使用了数组的运行时类型。在这种情况下,它可能是不安全的。这就是警告出现的原因。
回答by Philip Voronov
Because java compiler uses an implicit array creation for varargs, and java doesn't allow a generic array creation (because type argument is not reifiable).
因为 java 编译器对可变参数使用隐式数组创建,而 java 不允许创建通用数组(因为类型参数不可具体化)。
The code below is correct (these operations are allowed with arrays), so unchecked warning is needed:
下面的代码是正确的(数组允许这些操作),因此需要未经检查的警告:
public static <T> List<List<T>> createCombinations(List<T> ... lists) {
((Object[]) lists)[0] = new ArrayList<Integer>();
// place your code here
}
See a comprehensive explanation here
在此处查看全面说明