본문 바로가기

Java

[Effective Java] 아이템 27. 비검사 경고(unchecked warning)를 제거하라

더보기

아이템27 요약

- 비검사 경고는 제거하여 의도한대로 동작한다는 것을 확인하는 것이 좋다.

- 타입안전하다고 확신할 수 있는 코드라면 @SuppressWarnings를 달아 제거하는 것이 좋다.

- 제거하지 않고 그대로 두면, 다른 심각한 오류를 catch하지 못할 수 있다.

- @SuppressWarnings는 가능한 한 좁은 범위에 적용해 필요한 오류를 catch하자.

 

 

1. 할 수 있는 한 모든 비검사 경고를 제거하라.

모두 제거한다면 그 코드는 타입 안정성이 보장된다. 

런타임에 ClassCastException이 발생할 일이 없고, 의도한대로 동작한다는 걸 확신할 수 있다.

 

 

2. @SuppressWarnings는 가능한 좁은 범위에 적용하자.

  • 경고를 제거할 수는 없지만 타입 안전하다고 확신할 수 있다면 @SuppressWarnings("unchecked")애너테이션을 달아 경고를 숨길 수 있다.
  • 지역변수 선언부터 클래스 전체까지 어떤 선언에든 달 수 있다.

 

경고를 무시해도 될까?

안전하다고 검증된 비검사 경고를 제거하지 않으면, 진짜 문제를 알리는 새로운 경고가 묻힐 수 있다.

또한 넓은 범위에 적용한다면 심각한 경고를 놓칠 수 있으니 절대로 클래스 전체에 적용해서는 안된다.

때문에 한 줄이 넘는 메서드나 생성자에 달려있다면 지역변수 선언 쪽으로 옮기는 것이 좋다.

 

예시) [As-is]ArrayList의 toArray메서드

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;
}

위 코드를 컴파일하면 @copyOf()@ 부분에서 경고가 발생한다. 이 경고를 제거하려면 지역변수를 추가해야 한다.

return문에는 @SuppressWarnings("unchecked")를 다는게 불가능하기 때문이다.

 

 

예시) [To-be] ArrayList의 toArray메서드에 지역변수 추가

public <T> T[] toArray(T[] a) {
    if (a.length < size)
        // 생성한 배열과 매개변수로 받은 배열이 모두 T[]로 같으므로
        // 올바른 형변환이다.
        @SuppressWarnings("unchecked") 
        T[] result = (T[]) Arrays.copyOf(elementData, size, a.getClass()); 
        return result
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}