Java unchecked: unchecked generic array create for varargs parameter

I installed Netbeans to display unverified warnings in my Java code, but I do not understand the error in the following lines:

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>[]

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 exactly is going wrong, and how do I fix it, since I believe that leaving unchecked warnings in the code is not a good idea?

Forgot to mention, but I'm using Java 7.

Edit : now I see 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>...) 
+62
java generics variadic-functions
Jan 15 '14 at 8:46
source share
2 answers

As janoh.janoh mentioned above, varargs in Java is just syntactic sugar for arrays plus implicit array creation on the calling site. So

 List<List<String>> combinations = Utils.createCombinations(cocNumbers, vatNumbers, ibans); 

in fact

 List<List<String>> combinations = Utils.createCombinations(new List<String>[]{cocNumbers, vatNumbers, ibans}); 

But, as you know, new List<String>[] not allowed in Java for reasons that were raised in many other issues, but mainly due to the fact that arrays know their type of component at runtime and check at runtime added whether the elements are in accordance with their component type, but this check is not possible for parameterized types.

Anyway, instead of a failure, the compiler creates an array anyway. He does something similar to this:

 List<List<String>> combinations = Utils.createCombinations((List<String>[])new List<?>[]{cocNumbers, vatNumbers, ibans}); 

This is potentially dangerous, but not necessarily unsafe. Most varargs methods simply iterate over varargs elements and read them. In this case, it does not care about the runtime type of the array. This applies to your method. Since you are on Java 7, you must add the @SafeVarargs annotation to your method and you will no longer receive this warning. This annotation basically says that this method only cares about the types of elements, and not about the type of the array.

However, there are some varargs methods that use an array runtime type. In this case, it is potentially dangerous. That is why there is a warning.

+97
Jan 15 '14 at 23:42 on
source share

Since the java compiler uses implicit array creation for varargs, and java does not allow the creation of a shared array (because the type argument cannot be re-identified).

The correct code (these operations are allowed using arrays), so an unchecked warning is required:

 public static <T> List<List<T>> createCombinations(List<T> ... lists) { ((Object[]) lists)[0] = new ArrayList<Integer>(); // place your code here } 

Detailed description here

+11
Jan 15 '14 at
source share



All Articles