Open tonykang22 opened 1 year ago
<E extends Number>
, 선언할 수 있는 제네릭 타입을 Number를 상속(extends)했거나 구현한(implements)한 클래스로 제한한다.<E extends Number>
, Number 타입이 제공하는 메서드를 사용할 수 있다.<E extends Number & Serializable>
, 선언할 제네릭 타입은 Number와 Serializable를 모두 상속 또는 구현한 타입이어야 한다.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 static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
for (Integer arg : List.of(1, 2, 3))
stack.push(arg);
while (!stack.isEmpty())
System.out.println(stack.pop());
}
}
public class me/whiteship/chapter05/item29/technqiue1/Stack {
// compiled from: Stack.java
// access flags 0x2
// signature [TE;
// declaration: elements extends E[]
private [Ljava/lang/Object; elements
...
}
ClassCastException
이 발생한다.
public class Stack<E extends Number> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
// 배열 elements는 push(E)로 넘어온 E 인스턴스만 담는다.
// 따라서 타입 안전성을 보장하지만,
// 이 배열의 런타임 타입은 E[]가 아닌 Object[]다!
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
...
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
for (Integer arg : List.of(1, 2, 3))
stack.push(arg);
while (!stack.isEmpty())
System.out.println(stack.pop());
}
}
Number[]
배열을 사용해야 예외가 터지지 않게된다.public class Stack<E extends Number> {
private Number[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
@SuppressWarnings("unchecked")
public Stack() {
elements = new Number[DEFAULT_INITIAL_CAPACITY];
}
...
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
for (Integer arg : List.of(1, 2, 3))
stack.push(arg);
while (!stack.isEmpty())
System.out.println(stack.pop());
}
}
public class me/whiteship/chapter05/item29/bounded_type/Stack {
// compiled from: Stack.java
// access flags 0x2
private [Ljava/lang/Number; elements
...
}
아이템 29. 이왕이면 제네릭 타입으로 만들라.
핵심 정리
ClassCastException
등에서 자유로워질 수 있다.첫 번째 방법
: 제네릭 배열(E[]
) 대신 Object 배열을 생성한 뒤에 제네릭 배열로 형변환 한다.두 번째 방법
: 제네릭 배열 대신 Object 배열을 사용하고, 배열이 반환된 원소를 E로 형변환 한다.예시
E[]
를 사용한 경우의 Stack 구현이다.Object[]
를 사용한 경우의 Stack 구현이다.