이펙티브자바 - 32

참치돌고래·2022년 12월 27일
0

이펙티브 자바

목록 보기
17/21
post-custom-banner

가변인수 메소드

가변인수 메소드를 호출하면 가변인수를 담기 위한 배열이 생성된다.
매개변수화 타입의 변수가 타입이 다른 객체를 참조하면 힙 오염이 발생한다.

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();
    }
  • vargars 매개변수 배열에 아무것도 저장하지 않는다.
  • 그 배열을 신뢰할 수 없는 코드에 노출하지않는다.
profile
안녕하세요
post-custom-banner

0개의 댓글