public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new E[DEFAULT_INITIAL_CAPACITY]; // 예외 발생
}
public void push(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size == 0)
throw new EmptyStackException();
E result = elements[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
해결 방법1
제네릭 배열 생성을 금지하는 제약을 대놓고 우회
→ Object
배열을 생성한 다음 제네릭 배열로 형변환하는 방식
this.elements = new (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
해결 방법2
배열 타입을 E[] 에서 Object[]로 바꾸는 방법
public class Stack<E> {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(E e) {
elements[size++] = e;
}
public E pop() {
if (size == 0) {
throw new EmptyStackException();
}
@SupressWarnings("unchecked")
E result = (E) elements[--size];
elements[size] = null;
return result;
}
...
}
1번 방법이 가독성이 더 좋음
1번 방식에서는 형변환을 배열 생성 시 한번만 해주면 되지만, 2번 방식은 배열에서 원소를 읽을 때마다 형변환을 해줘야 함
1번 방식은 배열의 런타입 타입이 컴파일타임 타입과 달라 힙 오염을 일으킴
힙 오염? : https://inpa.tistory.com/entry/JAVA-☕-제네릭-힙-오염-Heap-Pollution-이란