이왕이면 제네릭 타입으로 만들기
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 = elements [--size];
elements [sizel = null; // 다 쓴 참조 해제
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays. copy0f (elements, 2 * size + 1);
}
}
Java
복사
•
위 코드를 제네릭 타입으로 바꾸어보자
•
일반 클래스를 제네릭 클래스로 만드는 첫 단계는 클래스 선언에 타입 매개 변수를 추가하는 것이다.
public class Stack<E> {
private E[] elements;
private int size = 0;
private static final in 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;
}
... // isEmpty와 ensureCapacity 메서드는 그대로다.
}
JavaScript
복사
•
E와 같은 실체화 불가 타입으로는 배열을 만들 수 없기 대문에, 제네릭 배열 생성을 우회하거나 elements 타입을 E[]에서 Object[] 바꾸면 해결된다.
// 제네릭으로 만드는 방법1
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
// 제네릭으로 만드는 방법2
public E pop() {
if (size == 0)
throw new EmptyStackException();
// push에서 E 타입만 허용하므로 이 형변환은 안전하다.
@SuppressWarnings("unchecked")
E result = (E) elements[--size];
elements[size] = null;
return result;
}
Java
복사
•
첫 번째 방법은 가독성이 좋고 형변환을 배열 생성 시 단 한번만 해주면 된다. 하지만 런타임 시에 컴파일타임 타입과 달라 힙 오염(heap pollution)을 일으킬 수있다.
•
두 번째 방법은 배열에서 원소를 읽을 때마다 형변환을 해주어야하지만, 힙 오염 걱정은 하지 않아도 된다.