Object기반의 스택은 제네릭 타입이 필요
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0
throw new EmptyStackException();
Object result = elemtns[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
해당 클래스는 제네릭 타입이어야한다
클라이언트가 스택에서꺼낸 객체를 형본환 -> 런타임 오류가 날 위험이있음
Object를 적절한 타입매개변수로 바꿔보면?
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0
throw new EmptyStackException();
Object result = elemtns[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
아이템28에서 설명한것처럼 E와 같은 실체화 불가타입으로배열을 만들수없다
두가지 방법이있다
1)하나는 Object 배열 생성하고 제네릭 배열로 형변환하는 것. 컴파일 경고가 난다.
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
배열 element가 private필드에 저장, 클라이언트에반환되거나 다른메서드에 전달되지 않아서 완전함.
가독성이 더좋음 ->배열타입을 E[]로 선언하여 해당타입의 인스턴스만받음을 어필
형변환을 생성시에만 해주면됨
배열의 런타임 타입이 컴파일 타입과 다르면 힙 오염을 일으킴
elements 필드의 타입을 E[]에서 Object[]로 변경
E는 실체화 불가타입으로 컴파일러는 런타임에 이뤄지는 형변환이 안전할지 증명할 방법이 없음.
//이 배열의 런타임 타입은 E[]가 아닌 Object[]다
public E pop() {
if (size == 0)
throw new EmptyStackException();
@SuppressWarnings("unchecked")
E result = (E) elements[--size];
elements[size] = null; // 다 쓴 참조 해제
return result;
}
컴파일러가 런타임에 이뤄지는 형변환이 안전한지알수없다
-형변환을 원소를 읽을때마가 해줘야함
제네릭타입안에서 리스트를 사용하는게 항상 가능하지않고
ArrayList도 결국 내부적으로 기본타입 배열을 쓴다
HashMap도 성능을 높일 목적으로 배열을 쓴다.