아이템 27 : 비검사 경고를 제거하라

📌 제네릭을 사용하면 만나게 되는 경고들

제네릭을 사용하면 아래와 같이 많은 컴파일러 경고를 보게 된다.
비검사 형 변환 경고
비검사 메서드 호출 경고
비검사 매개변수화 가변인수 타입 경고
비검사 변환 경고
...

📌 컴파일러를 이용하여 비검사 경고를 제거하자

대부분의 비검사 경고는 쉽게 제거할 수 있다. 컴파일러가 무엇이 잘못됐는지 친절하게 설명해준다. 인텔리제이에서는 노란색 줄로 표기까지하며 알려준다. 즉, 아래와 같은 코드로 작성하면 IDE에서 쉽게 수정할 수 있다.
List<User> users = new ArrayList(); //수정하기 전 List<User> users = new ArrayList<User>(); //컴파일러가 알려준 대로 수정
Java
위와 같이 컴파일러가 알려준 대로 수정할 수 있지만, 단축키로 수정하게 되면 아래와 같이 자동으로 변환하게 된다. 아래 코드는 자바 7부터 지원하는 다이아몬드 연산자(<>)만으로 해결할 수 있다. 즉, 컴파일러가 올바른 실제 타입 매개변수를 추론한다.
List<User> users = new ArrayList<>();
Java

📌 가능하면 모든 비검사 경고를 제거하자

할 수 있는 한 모든 비검사 경고는 제거해야 한다. 타입 안정성이 보장되기 때문이다. 그러면 런타임에 ClassCastException이 발생할 수 없고, 의도한 대로 잘 동작하리라 확신할 수 있다.

📌 경고를 제거할 수 없다면?

경고를 제거할 수 없다면 타입이 안전하다고 @SuppressWarnings("unchecked")로 확신할 수 있어야 한다. 해당 어노테이션을 달면 경고를 숨길 수 있다.

@SuppressWarnings 주의할 점

타입이 안전하다는 것을 검증하지 않고, 숨긴다면 여러 문제가 발생할 수 있다.
런타임에 ClassCastException을 던질 수 있다.
안전하다고 검증된 비검사 경고를 그대로 두는 것도 문제가 생길 수 있다.
진짜 문제를 알리는 새로운 경고를 눈치채지 못할 수 있다. 따라서 수 많은 거짓 경고 속에 새로운 경고가 파묻힐 수 있다.
해당 애너테이션은 가능한 좁은 범위에 적용해야 한다. ex) 변수, 짧은 메서드, 생성자
해당 애너테이션은 개별 지역변수 선언부터 클래스 전체까지 어떤 선언에도 달 수 있다.
자칫 심각한 경고를 놓칠 수 있어, 절대로 클래스 전체에 적용해서는 안 된다.
메서드나 클래스 전체에 달게 되면 필요 이상으로 범위가 넓어지게 된다.
선언에만 달 수 있고, return 문에는 달 수 없다.
해당 애너테이션 사용 시, 그 경고를 무시해도 안전한 이유를 항상 주석으로 남겨야 한다.

📌 참고 자료

TOP