Item 24. 무점검 경고(unchecked warning)를 제거하라.

제네릭을 써서 새로 만든 코드가 한번에 깔끔하게 컴파일 되리라는 기대는 버리도록 하자.

제네릭으로 프로그램하다 보면 다음과 같은 많은 컴파일 경고 메시지를 보게 된다.

모든 무점검 경고는, 가능하면 없애야 한다. 전부 없애고 나면 형 안전성(typesafe)이 보장된다.

제거 할 수 없는 경고 메시지는 형 안전성이 확실할 때만 @SuppressWarnings(“unchecked”) 어노테이션(annotation)을 사용해 억제해야 된다.

아래의 코드는 ArrayList 클래스의 일부이다.

public <T> T[] toArray(T[] a){
    if(a.length < size)
        return (T[]) Arrays.copyOf(elements, size, a.getClass());
    System.arraycopy(elements, 0, a, 0, size);
    if(a.length > size)
        a[size] = null;
    return a;
}

ArrayList클래스를 컴파일해 보면 다음과 같은 경고 메시지가 출력된다.

ArrayList.java:305: warning: [unchecked] unchecked cast
found : Object[], required: T[]
    return (T[]) Arrays.copyOf(elements, size, a.getClass());

함수 전체에 SuppressWarnings어노테이션을 붙일수 있으나, 그 보다는 문제가 발생하는 지점에 정확히 붙이는 것이 좋다.

// @SuppressWarnings 정의를 함수 단위에 적용할수 있으나, 적용 범위를 줄이기 위해 지역 변수 사용함
public <T> T[] toArray(T[] a){
    if(a.length < size){
        /*
            아래의 형 변환은 배열의 자료형이 인자로 전달된 자료형인 T[]와 같으므로 
            형 변환이 정확하므로 @SuppressWarnings("unchecked")처리 함
         */
        @SuppressWarnings("unchecked")
        T[] result = (T[]) Arrays.copyOf(elements, size, a.getClass());
        return result;
    }
    System.arraycopy(elements, 0, a, 0, size);
    if(a.length > size)
        a[size] = null;
    return a;
}

@SuppressWarnings(“unchecked”) 어노테이션을 사용할 때마다, 왜 형 안전성을 위반하지 않는지 주석을 통해 정확히 밝히도록 하자.

무점검 경고(unchecked warning)는 중요하다. 무시하지 말자. 모든 점검 경고는 프로그램 실행 도중에 ClassCastException이 발생할 가능성을 나타낸다. 그런 경고 메시지는 최선을 다해제거하자. 경고를 제거할수는 없으나, 내가 만든 코드가 형 안전성을 보장한다는 사실을 입증할 수 있다면, @SuppressWarnings("unchecked")어노테이션을 사용해 해당 경고를 억제하되 어노테이션 적용 범위는 최소화 하자. 그리고, 경고 메시지를 억제한 이유를 주석을 통해 알리자.