가변인수 메소드를 호출하면 가변인수를 담기 위한 배열이 생성된다.
매개변수화 타입의 변수가 타입이 다른 객체를 참조하면 힙 오염이 발생한다.
static void dangerous(List<String>... stringLists) {
List<Integer> intList = List.of(42);
((Object[]) stringLists)[0] = intList;
String s= stringLists[0].get(0);
}
컴파일러는 단순히 경고를 던지고, 실행시 castException
이 발생한다.
이처럼 타입 안정성이 깨지니 제너릭 배열 매개변수에 값을 저장하는 것은 안전하지 않다.
@SafeVarags
어노테이션 : 메서드 작성자가 크 메서드가 타입 안전함을 보장할 수 있는 장치.
컴파일러는 이 어노테이션을 통해 안전하지 않을 수 있다는 경고를 하지 않는다.
가변변수 메소드를 호출하면 해당 컬렉션으로 배열이 생성된다고 하였다.
아래의 toArray 메서드가 호출되며 T 인스턴스 2개를 담을 매개변수 배열을 만든다.
Object[] 형대로 생성이 될텐데 main함수에서 타입으로 담은 String[]은 caseException
을 발생할 것이다.
Object[] 가 String[] 하위타입이 아니기 때문.
public static void main(String[] args) {
String[] strings = pickTwo("a", "b", "c");
}
static <T> T[] toArray(T... args) {
return args;
}
static <T> T[] pickTwo(T a, T b, T c) {
switch(ThreadLocalRandom.current().nextInt(3)) {
case 0: return toArray(a, b);
case 1: return toArray(a, c);
case 2: return toArray(b, c);
}
throw new AssertionError();
}