[java] Java unchecked : varargs 매개 변수에 대해 확인되지 않은 일반 배열 생성
Java 코드에서 확인되지 않은 경고를 표시하도록 Netbeans를 설정했지만 다음 줄에서 오류를 이해하지 못했습니다.
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의 varargs는 배열에 대한 구문 설탕과 호출 사이트에서 배열의 암시 적 생성에 불과합니다. 그래서
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에서는 허용되지 않습니다. 다른 많은 질문에서 다룬 이유로 인해 배열이 런타임시 구성 요소 유형을 알고 있으며 추가 된 요소가 해당 구성 요소와 일치하는지 런타임에 확인해야합니다. 유형이지만 매개 변수화 된 유형에는이 검사가 불가능합니다.
어쨌든 실패하지 않고 컴파일러는 여전히 배열을 만듭니다. 다음과 유사한 작업을 수행합니다.
List<List<String>> combinations =
Utils.createCombinations((List<String>[])new List<?>[]{cocNumbers, vatNumbers, ibans});
이것은 잠재적으로 안전하지 않지만 반드시 안전하지 않은 것은 아닙니다. 대부분의 varargs 메서드는 단순히 varargs 요소를 반복하고 읽습니다. 이 경우 배열의 런타임 유형은 신경 쓰지 않습니다. 이것은 당신의 방법의 경우입니다. Java 7을 사용 @SafeVarargs
중이므로 메소드에 주석을 추가해야합니다. 그러면 더 이상이 경고가 표시되지 않습니다. 이 주석은 기본적으로이 메서드는 배열의 유형이 아닌 요소의 유형에만 관심이 있다고 말합니다.
그러나 배열의 런타임 유형을 사용하는 일부 varargs 메소드가 있습니다. 이 경우 잠재적으로 안전하지 않습니다. 그것이 경고가있는 이유입니다.
답변
Java 컴파일러는 varargs에 대해 암시 적 배열 생성을 사용하고 java는 일반 배열 생성을 허용하지 않기 때문입니다 (유형 인수를 수정할 수 없기 때문에).
아래 코드는 정확하므로 (이러한 작업은 배열에서 허용됨) 확인되지 않은 경고가 필요합니다.
public static <T> List<List<T>> createCombinations(List<T> ... lists) {
((Object[]) lists)[0] = new ArrayList<Integer>();
// place your code here
}