이펙티브 자바 아이템 27 - 비검사 경고를 제거하라 - 핵심 정리
아이템 27 - 비검사 경고를 제거하라 - 핵심 정리
이 글은 백기선 님의 이펙티브 자바 강의와 이펙티브 자바 3 / E 편을 참고하여 작성하였습니다.
컴파일러가 컴파일 할 때 에러 와 경고 두가지로 나누어진다.
에러 는 컴파일이 실패하는 것이고, 경고 는 컴파일에 실패하지는 않지만 권장하지 않고, 위험성이 있을 때 나타난다.
경고 는 컴파일러시 경고 메세지 를 출력할 수 있다.
이 경고 중에서도 비검사 (unchecked) 란 컴파일러가 타입 안정성을 확인하는데 필요한 정보가 충분치 않을 때 발생하는 경고이다.
public class SetExample {
public static void main(String[] args) {
Set names = new HashSet();
Set<String> strings = new HashSet();
}
}
타입 안정성은 어떠한 컨테이너 역활을 하는 인스턴스나 클래스 타입에 제네릭 타입을 사용한다.
그럼에도 불구하고 로 타입 을 사용한다면 비검사 경고 가 발생한다.
이렇게 비검사 경고 가 발생했을 때는 다음 두가지 규칙을 따라야한다.
- 비검사 경고를 제거할 수 있으면 가능한한 모두 제거해야한다.
- 제거할 수 없는 경우
@SuppressWarnings
을 붙여주어야 한다.
Set names = new HashSet();
로 타입 을 사용했기 때문에 비검사 경고 가 발생한다.
자바 7 부터 지원하는 다이아몬드 연산자 (<>) 를 사용해 타입을 한번만 선언해도 된다.
// Set<String> names = new HashSet<String>();
Set<String> names = new HashSet<>();
위처럼 다이아몬드 연산자 (<>) 를 사용해 타입 선언을 생략할 수 있다.
Set<String> strings = new HashSet();
에서도 비검사 경고가 발생하는데
Set<String> strings = new HashSet<>();
위처럼 다이아몬드 연산자 (<>) 를 사용해 수정해준다.
@SuppressWarnings
public class ListExample {
private int size;
Object[] elements;
public <T> T[] toArray(T[] a) {
if (a.length < size) {
/**
* 이 애노테이션을 왜 여기서 선언했는지..
*/
@SuppressWarnings("unchecked")
T[] result = (T[]) Arrays.copyOf(elements, size, a.getClass());
return result;
}
System.arraycopy(elements, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
}
@SuppressWarnings
같은 경우는 타입 안정성을 보장할 수 있는 방법은 없지만 실질적으로 안전할 때 사용한다.
실질적으로 안전하지만 비검사 경고 를 제거할 방법이 없을 때는 @SuppressWarnings(“unchecked”)
을 사용한다.
@SuppressWarnings
자체는 경고 자체를 무시해주는 애노테이션이다.
@SuppressWarnings
를 권장하는 이유는 해당 경고 이외에 다른 경고가 발생하면 확인 할 수 있기 때문이다.
@SuppressWarnings
를 사용하지 않는다면 컴파일러에서 경고가 발생했을 때 이미 알고있는 경고인지 아닌지 알기가 어렵다.
@SuppressWarnings(“unchecked”)
은 가능한 좁은 범위에 적용해야한다.
만약 메서드에 붙인다면 메서드 전체 범위에서 비검사 경고 를 숨겨주기 때문에 내가 알지 못하는 비검사 경고 역시 숨겨준다.
그래서 @SuppressWarnings(“unchecked”)
은 가능한 좁은 범위에 적용해야한다.
그 뒤 주석을 통해 @SuppressWarnings(“unchecked”)
을 붙인 이유에 대해 설명하면 더더욱 좋다.