[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개의 댓글