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[size] = null;
return result;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
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;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
E
를 사용한다. 그런 후 Object를 적절한 타입 매개 변수로 바꾸고 컴파일 하면 하나 이상의 오류가 발생하는데, 그 이유는 E
는 실체화 불가 타입이기 때문이다. public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
@SuppressWarnings("unchecked")
어노테이션을 사용해 경고를 숨겨서 사용할 수 있다.public class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
//우회한다
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[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;
}
public boolean isEmpty() {
return size == 0;
}
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
public class Stack<E> {
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(E e) {
ensureCapacity();
elements[size++] = e;
}
public E pop() {
if (size == 0)
throw new EmptyStackException();
@SuppressWarnings("unchecked")
E result = (E) elements[--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);
}
}
E
가 실체화 불가 타입이기 때문에 런타임에 이뤄지는 형변환이 안전한지 증명할 방법이 없다@SuppressWarnings("unchecked")
E result = (E) elements[--size];
Stack 처럼 대다수의 제네릭 타입은 타입 매개변수에 아무런 제약을 두지 않는다. Stack<Object>, Stack<int[]>, Stack<List<String>>, Stack 등 어떤 참조타입으로도 Stack을 만들 수 있다.
타입 매개변수에 제약을 두는 제네릭 타입도 있다.
class DelayQueue<E extends Delayed> implements BlockingQueue<E>
타입 매개변수 목록인 <E extends Delayed>
는 java.util.concurrent.Delayed
의 하위타입만 받는다는 뜻이다. 이러한 타입 매개변수를 한정적 타입 매개변수라고 한다. 모든 타입은 자기 자신의 하위 타입이기 때문에 DelayQueue<Delayed\>
로도 사용할 수 있음을 기억하자