# ITEM27 비검사 경고를 제거하라
# 제너렉의 컴파일 경고들
- 비검사 형변환 경고
- 비검사 메서드 호출 경고
- 비검사 매개변수화 가변인수타입 경고
- 비검사 변환 경고
# unchecked warning
unchecked warning, 확인되지 않은 경고, 비검사 경고
cast 로 인해, 프로그램이 다른 곳에서 예외를 throw 할 수 있음을 프로그래머에게 알려준다.
- 비검사 경고를 모두 제거했을 때
- 타입 안전성 보장
- 런타임에 ClassCastException 이 나타나지 않고 의도대로 잘 동작한다.
# 비검사 경고 제거
new HashSet()
의 타입 매개변수를 명시하지 않았다.
Set<Lark> exaltation = new HashSet();
1
다음은 잘못된 코드임을 컴파일러를 통해 알 수 있다.
(javac 명령줄 인수에 -Xlint:uncheck 옵션 추가)
...java:line: waring: [unchecked] unchecked conversion
Set<Lark> exaltation = new HashSet();
required: Set<Lark>
found: HashSet
1
2
3
4
2
3
4
Set<Lark> exaltation = new HashSet<Lark>();
1
혹은 자바7 부터, 다이아몬드 연산자<> 사용 → 컴파일러가 타입 매개변수 추론
Set<Lark> exaltation = new HashSet<>();
1
# @Suppress Warnings("unchecked")
# 사용 상황
- 경고를 제거할 수는 없고,
- 타입 안전의 확신이 있을 경우
- 경고를 무시해도 안전한 이유를 항상 주석으로 남겨야 한다.
위와 같은 경우에 사용을 하지 않으면,
- 제거하지 않은 수 많은 경고 → 진짜 문제를 알리는 새로운 경고가 파묻힐 수도 있음
# 사용 범위
모든 선언에서 사용가능
- 개별 지역변수 선언 ~ 클래스 선체 선언
가능한한 좁은 범위에 적용해야 함.
- 변수 선언
- 아주짧은 메서드
- 생성자
클래스 전체에 적용할 경우
- 자칫 심각한 경고를 놓칠 수 있다.
# 한줄이 넘는 메서드/생성자의 @SuppressWarnings
한줄이 넘는 메서드/생성자의 @SuppressWarnings 는 지역 변수 선언 쪽으로 옮긴다
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;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
ArrayList 를 컴파일 하면, 다음 경고가 발생한다.
Array.List.java:305: warning: [unchecked] unchecked cast
return (T[]) Arrays.copyOf(elements, size, a.getClass());
required: T[]
found: Object[]
1
2
3
4
2
3
4
지역 변수를 추가해 @SuppressWarnings 의 범위를 좁힌다.
public <T> T[] toArray(T[] a) {
if (a.length < size) {
@SuppressWarnings("unchecked")
T[] result = (T[])Arrays.copyOf(elements, size, a.getClass());
return result;
}
// ...
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8