[Effective Java] 아이템 27 : 비검사 경고를 제거하라

Loopy·2022년 7월 29일
0

이펙티브 자바

목록 보기
26/76
post-thumbnail

제네릭을 사용하면서 마주칠 수 있는 컴파일러 경고(비검사 경고)들은 다음과 같다.
이 중 비검사 경고는 제일 쉽게 제거 가능하기 때문에, 할 수 있는 한 모든 비검사 경고를 제거하는 것이 좋다.

☁️ 비검사 경고 제거 방법

1. 다이아몬드 연산자

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

Set<Lark> exaltation = new HashSet();

javac 명령줄 인수에 -Xlint:uncheck 옵션을 추가하면은 컴파일러가 어디가 잘못되었는지 알려준다.

Venery.java:4: warning: [unchecked] unchecked conversion Set exaltation = new HashSet();

required: Set
found: HashSet

참고로, 자바 7에서부터 지원하는 다이아몬드 연산자( <> )을 사용하면 컴파일러가 올바른 실제 타입 매개변수를 추론해주기 때문에 직접 타입 매개변수를 명시하지 않아도 된다.

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

☁️ 비검사 경고를 제거할 수 없는 경우

@SuppressWarnings("unchecked")

경고를 제거할 수는 없지만, 타입이 안전하다고 확신할 수 있다면 @SuppressWarnings("unchecked") 어노테이션을 통해 경고를 숨길 수 있다.

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

@Target 에서 볼 수 있듯이 거의 모든 곳에 붙일 수 있지만 가능한 한 좁은 범위에 적용하는 것이 좋다. 타입 안전성을 검증하지 않았다면, 경고 없이 컴파일 되지만 런타임에는 여전히 ClassCastException 을 던지기 때문이다.

만약 한줄이 넘는 메서드나 생성자에 달렸다면, 아래의 예제와 같이 지역변수 선언 쪽으로 옮기는 것을 권장한다.

예제

public <T> T[] to Array(T[] a) {
  	if(a.length < size)
        return (T[]) Arrays.copyOf(elements, size, a.getClass());
    ...
}

해당 코드를 컴파일하면 다음과 경고가 발생한다.

지역변수를 추가하여, @SuppressWarnings 의 범위를 좁힐 수 있다.

public <T> T[] to Array(T[] a){
  	if(a.length < size) {
        @SupressWarnings("unchecked")
        T[] result = (T[]) Arrays.copyOf(elements, 0, a, 0, size); 
        return result;
    }
}

마지막으로, 해당 어노테이션을 사용할 때면 그 경고를 무시해도 안전한 이유를 항상 주석으로 남겨야 한다. 다른 사람이 코드를 이해하는데 도움이 되며, 코드를 잘못 수정하여 타입 안전성을 잃는 상황을 줄여주기 때문이다.

profile
개인용으로 공부하는 공간입니다. 피드백 환영합니다 🙂

0개의 댓글

관련 채용 정보