未选中Java:为varargs参数未经检查的通用数组创建 [英] Java unchecked: unchecked generic array creation for varargs parameter

查看:205
本文介绍了未选中Java:为varargs参数未经检查的通用数组创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经设置Netbeans在我的Java代码中显示未经检查的警告,但我无法理解以下几行的错误:

 私人列表< String> cocNumbers; 
私人列表< String> vatNumbers;
私人列表< String>伊班人;
私人列表< String>银行;
...
列表< List< String>>组合= Utils.createCombinations(cocNumbers,vatNumbers,ibans);

给出:

<$ c $方法来源:

$ <$> $ $ $ $ $ $ $ $ $

  / ** 
*返回输入数组列表的所有可能组合列表。
*
*示例:[[A,B],[0,1,2]]
*返回:[[A, 0,[A,1],[A,2],[B,0],[B,1],[B 2]]
*
* @param< T>类型参数
* @param元素列表数组
* @return输入列表的所有可能组合
* /
public static< T>列表与LT;列表与LT; 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]参数化变量类型可能堆污染列表< T> 
其中T是一个类型变量:
T extends在方法< T> createCombinations(List< T> ...)中声明的对象


 列表< List< String>>组合= 
Utils.createCombinations(cocNumbers,vatNumbers,ibans);

其实是

 列表与LT;列表与LT;字符串>>组合= 
Utils.createCombinations(新列表< String> [] {cocNumbers,vatNumbers,ibans});

但您可能知道, new List< String> [] 在Java中是不允许的,因为在其他许多问题中已经讨论过,但主要是因为数组在运行时知道它们的组件类型,并且在运行时检查添加的元素是否匹配它的组件类型,但是这种检查对于参数化类型是不可能的。



无论如何,编译器仍然会创建数组,而不是失败。它的作用类似于此:

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

这可能是不安全的,但不一定是不安全的。大多数可变参数方法只是迭代可变参数元素并读取它们。在这种情况下,它不关心数组的运行时类型。你的方法就是这种情况。由于您使用的是Java 7,因此您应该将 @SafeVarargs 注释添加到您的方法中,并且您不会再收到此警告。这个注解基本上说,这个方法只关心元素的类型,而不关心数组的类型。



但是,有一些可变参数方法可以使用运行时数组的类型。在这种情况下,它可能是不安全的。这就是为什么警告在那里。


I have set Netbeans to show unchecked warnings in my Java code, but I am failing to understand the error on 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 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.

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>...)

解决方案

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

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.

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.

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.

这篇关于未选中Java:为varargs参数未经检查的通用数组创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆