Warning:(9, 33) java: Possible heap pollution from parameterized vararg type T Warning:(15, 35) java: unchecked generic array creation for varargs parameter of type T[] Warning:(16, 35) java: unchecked generic array creation for varargs parameter of type T[] Warning:(17, 35) java: unchecked generic array creation for varargs parameter of type T[]
실행 결과
1 2 3 4
Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String; ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader 'bootstrap') at com.github.sejoung.codetest.generics.varargs.PickTwo.main(PickTwo.java:23)
Process finished with exit code 1
위에 코드에서는 힙오염이 발생한다. 그이유는 자신의 제네릭 매개변수 배열의 참조를 노출 해서 이다.
// 제네릭 varargs 배열 매개변수에 값을 저장하는 것은 안전하지 않다. (191-192쪽) publicclassDangerous{ // 코드 32-1 제네릭과 varargs를 혼용하면 타입 안전성이 깨진다! (191-192쪽) staticvoiddangerous(List<String>... stringLists){ List<Integer> intList = List.of(42); Object[] objects = stringLists; objects[0] = intList; // 힙 오염 발생 String s = stringLists[0].get(0); // ClassCastException }
publicstaticvoidmain(String[] args){ dangerous(List.of("There be dragons!")); } }
컴파일 메시지
1 2 3
Warning:(8, 43) java: Possible heap pollution from parameterized vararg type java.util.List<java.lang.String> Warning:(16, 18) java: unchecked generic array creation for varargs parameter of type java.util.List<java.lang.String>[]
실행결과
1 2 3 4 5 6
Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap') at com.github.sejoung.codetest.generics.varargs.Dangerous.dangerous(Dangerous.java:12) at com.github.sejoung.codetest.generics.varargs.Dangerous.main(Dangerous.java:16)
// 코드 32-3 제네릭 varargs 매개변수를 안전하게 사용하는 메서드 (195쪽) publicclassFlattenWithVarargs{ @SafeVarargs static <T> List<T> flatten(List<? extends T>... lists){ List<T> result = new ArrayList<>(); for (List<? extends T> list : lists) result.addAll(list); return result; }