Item 27. 비검사 경고를 제거하라

심규환·2022년 2월 17일
0

Effective Java

목록 보기
25/29

먼저 비검사 경고란, 컴파일러의 경고를 나타낸다. 제네릭을 사용하면 이러한 비검사 경고가 많이 발생하는데. 최대한 줄일 수 있는 것이 좋다. 아래의 코드를 살펴보자.

Set<Lark> exaltation = new HashSet();

위의 코드를 그대로 컴파일하면 new HashSet()에 타입 매개변수를 명시하지 않았다는 경고가 발생한다. 이는 new HashSet<Lark>() 또는 new HashSet<>()로 바꾸면 경고는 사라지게 된다.
다이아몬드 연산자(<>)를 하면 컴파일러가 올바른 실제 타입 매개변수를 추론해서 넣어준다.
이렇듯 할 수 있는 모든 비검사 경고를 제거하자. 모두 제거한다면 그 코드는 타입 안정성이 보장된다.

만약 경고를 제거할 수는 없지만 타입이 안전하다라고 보장이 되고 확신한다면 @SuppressWarnings("unchecked") 애너테이션을 달아주자. 이 애너테이션을 달아주면 비검사 경고를 억제하여 나오지 않게 해준다.
하지만 안전하다고 보장되지 않고 사용한다면 경고는 나오지 않고 형변환 에러(ClassCastException)와 같은 에러가 런타임중 날라오게 된다.

@SupressWarnings 애너테이션은 개별 지역변수 선언부터 클래스 전체까지 어떤 선언에도 달 수 있다.
다음은 @SupressWarnings 애너테이션을 사용한 예시이다. ArrayList에서 배열을 복사해서 매개변수 배열에 넣어주는 toArray 메서드이다.

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

이를 그대로 컴파일하면
return (T[]) Arrays.copyOf(elements, size, a.getClass()); 이 부분에 경고가 발생한다. 매개변수로 들어온 T[] areturn에 생성된 배열이 같은 타입인지 확인이 필요하기 때문이다.

하지만 생성된 배열과 매개변수로 받은 배열이 모두 T[]으로 같기 때문에 올바른 형변환이다. return 문에 @SupressWarnings 애너테이션을 바로 넣을 수 없기 때문에 따로 지역변수 result를 선언하자. (메소드 자체에 선언이 가능하지만 범위가 넓기 때문에 지역변수로 최대한 범위를 최소화 하자.)

@SupressWarnings("unchecked") T[] result = (T[]) Arrays.copyOf(elements, size, a.getClass());
return result;

여기서 @SupressWarnings("unchecked")를 사용할 때면 그 경고를 무시해도 되는 이유를 항상 주석으로 남겨주도록 하자. 그래야 다른 사람이 봐서 코드를 이해할 수 있게 된다.

profile
장생농씬가?

0개의 댓글