제네릭과 가변인수를 함께 쓸 때는 신중하자
가변 인수 메소드를 호출하면 가변인수를 담기 위한 배열이 자동으로 만들어진다. 메소드 선언히 실체화 불가 타입(제네릭)으로 매개 변수를 선언하면 컴파일러가 경고를 보낸다. 힙 오염의 여지가 있기 때문이다. 매개변수화 타입의 변수가 타입이 다른 객체를 참조하면 힙 오염이 발생한다. 이는 컴파일러의 자동 형변환 실패할 수 있으니 제네릭 의 근간이 무너진다.
그런데, 왜 가변 인자를 메소드 시그니처에 선언할 수 있게 했을까? 편하니까다. 놀랍게도 말이다. 자바 7 이전까지는 호출자쪽에서 발생하는 경고를 무시할 수 없었다.
@SafeVarargs이 자바7에서 추가되면서 경고를 숨길 수 있게 됐다. 당연히 @SafeVarargs를 쓸 때는 정당한 사유가 있어야 하며 어노테이션 만으로 메소드가
type-safe 함을 보장한다는 의미를 가지고 있으므로 주의해야한다. 추가로 당연히 주석도 달아야 한다.
다시 돌아가서 제네릭 varargs를 안전하게 쓰려면 어떻게 하면 좋을까? readOnly로 인덱스에 접근하여 수정하지만 않으면 된다. 혹은 배열을 방어적 복사를 해서 뱉으면 된다.