언어/Effective Java
이펙티브 자바 Item29 - 이왕이면 제네릭 타입을 사용하라
now0204
2024. 6. 4. 14:37
Object배열로 이루어진 스택
public class ArrayStack {
private Object[] elements;
private int size;
public ArrayStack() {
this.elements = new Object[10];
}
public void push(Object obj) {
elements[size++] = obj;
}
public Object pop() {
if (size == 0) {
throw new IllegalArgumentException("스택에 아무것도 없습니다");
}
Object result = elements[--size];
elements[size] = null;
return result;
}
}
- 클라이언트는 이를 사용하기 위해서 매번 형변환을 해야한다. 또한 형 변환이 성공한다는 보장도 없다.
이를 제네릭으로 바꾸며 제네릭의 장점을 알아보자
먼저 모든 Object를 제네릭 E로 변경하면 컴파일 에러가 발생한다.
public GenericStack(){
this.elements = new E[10];
}
- E는 소거되기 때문이다!
public GenericStack() {
this.elements = (E[])new Object[10];
}
- E와 같은 실체화 불가 타입은 배열 생성이 안됨~~!
- 아래와 같이 우회할 수 있다. - 필드에 E 배열 타입을 가지고 있음으로써 이 Stack은 E 타입의 인스턴스만 받을 수 있음을 확신할 수 있다.
- 다만, 힙오염, 런타임타입 E 컴파일 타입 Object
- 런타임과 컴파일타임 타입이 다르면 Unchecked Warning과 ClassCastException이 발생할 가능성이 있는 상황
Set s = new TreeSet<Integer>();
Set<String> ss = s; // unchecked warning
s.add(new Integer(42));
- @SupressWarnings를 추가해서 warning을 잡을 수 있다.
결론적으로 기존 타입 중 제네릭이 있어야 하는게 있다면, 제네릭 타입으로 변경하자
참고자료
https://javabom.tistory.com/38