ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Item 27. 비검사 경고를 제거하라
    백수의 개발/이펙티브 자바 2019. 10. 15. 12:19

    비검사 경고

    제네릭을 사용하기 시작하면 수많은 컴파일러 경고를 보게된다.

    비검사 형변환 경고, 비검사 메서드 호출 경고, 비검사 매개변수화 가변인수 타입 경고, 비검사 변환 경고 등이다.

     

    대부분의 비검사 경고는 쉽게 제거할 수 있다. 아래의 코드를 살펴보자.

    Set<Lark> exaltation = new HashSet();

    이를 컴파일하면 컴파일러는 무엇이 잘못됐는지 친절히 설명해준다.

    warning: [unchecked] unchecked conversion
    Set<Lark> exaltation = new HashSet();
                           ^
    required: Set<Lark>
    found:    HashSet

    아래처럼 컴파일러가 알려준 대로 수정하면 경고가 사라진다.

    Set<Lark> exaltation = new HashSet<>();

    이와 달리 제거하기 훨씬 어려운 경고도 있다. 그러나 할 수 있는 한 모든 비검사 경고를 제거해라.

    만약, 경고를 제거할 수는 없지만 타입 안전하다고 확신한다면 @SuppressWarnings("unchecked")애너테이션을 달아 경고를 숨기자.

    @SuppressWarnings 애너테이션은 항상 가능한 한 좁은 범위에 적용하자.

     

    ArrayList에서 가져온 toArray 메서드를 살펴보자.

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

    이를 컴파일하게 되면 Arrays.copyOf(elementData, size, a.getClass())에서 unchecked cast경고가 발생한다.

    그러나 생성한 배열과 매개변수로 받은 배열의 타입이 모두 T[]로 같다는 것을 보증하고, 오류가 나지 않을 것을 확신할 수 있다.

    이러한 경우 아래처럼 애너테이션을 달아 그 경고를 무시할 수 있게 해주고, 그 경고를 무시해도 안전한 이유를 주석으로 남겨주면 된다.

    @SuppressWarnings("unchecked")
    public <T> T[] toArray(T[] a) {
        if (a.length < size)
            // Make a new array of a's runtime type, but my contents:
            return (T[]) Arrays.copyOf(elementData, size, a.getClass());
        System.arraycopy(elementData, 0, a, 0, size);
        if (a.length > size)
            a[size] = null;
        return a;
    }

    마무리

    비검사 경고는 중요하니 무시하지 말자. 모든 비검사 경고는 런타임에 ClassCastException을 일으킬 수 있는 잠재적 가능성을 뜻하니 최선을 다해 제거하라. 경고를 없앨 방법을 찾지 못하겠다면, 그 코드가 타입 안전함을 증명하고 가능한 한 범위를 좁혀 @SuppressWarnings 애너테이션으로 경고를 숨겨라. 그리고 경고를 숨기기로 한 근거를 주석으로 남겨라

    댓글

Designed by Tistory.