[Effective Java] 아이템29 - 이왕이면 제너릭 타입으로 만들라
Stack
클래스를 <E>
Type을 받아서 제네릭 스택으로 만드는 과정에서 생기는 컴파일 에러와 Unchecked Exception을 살펴본다.
(보통 형변환 런타임 오류 때문에 제네릭을 사용한다고 생각하면 될 것 같다.)
클라이언트에서 직접 형변환을 안해도 되게끔 제네릭 타입으로 만들자.
private E[] elements;
elements = new E[DEFAULT_INITIAL_CAPACITY];
위와 같은 코드를 짰을때, 아래와 같은 컴파일 에러가 발생한다.
Stack,java:8: generic array creation
elements = new E[DEFAULT_INITIAL_CAPACITY];
아이템28에서 설명한 것처럼, E
는 실체화가 불가하기 때문에 배열로 만들 수 없다.
1. Object 배열을 생성한 뒤 제네릭 배열로 형변환
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
이렇게 하면 컴파일러는 오류 대신 경고를 내보낸다.
Stack.java:8: warning: [unchecked] unchecked cast found: Object[], required: E[]
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
E
타입이 안전하지 않다는 것이다. 하지만 개발자가 타입 안전성을 해치지 않음을 확인했을 경우에는 @SuppressWarnings
어노테이션으로 해당 경고를 숨기면 된다.
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
이 때, 배열의 런타임 타입(E[])가 컴파일타임(Object[])와 달라서 heap pollution
을 일으킨다. (아이템32)
2. elements 필드의 타입을 E[]
에서 Object[]
로 변경한다.
Stack.java:19: incompatible types found: Object, required: E
E result = elements[—size];
Object[]
배열인 elements에서 원소를 꺼낼 때 형변환 Unchecked Exception이 있는 것이다. 타입 안전한지 보장이 된다면 이 또한 SuppressWarnings
를 추가해주면 된다.
@SuppressWarnings("unchecked") E result = (E) elements[—size];
댓글남기기