Item 29. Generic Type
์ด์์ด๋ฉด ์ ๋ค๋ฆญ ํ์ ์ผ๋ก ๋ง๋ค๋ผ
ํด๋ผ์ด์ธํธ์์ ์ง์ ํ๋ณํํด์ผํ๋ ๊ฒ๋ณด๋จ ํ๋ณํ ์์ด ์ฌ์ฉํ ์ ์๋๋ก ํ๋ ๊ฒ์ด ์ข๋ค. ์ด๋ ๊ฒ ๊ตฌํํ๊ธฐ ์ํด์ ์ ๋ค๋ฆญ ํ์ ์ผ๋ก ๋ง๋ค์ด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ ์๋ก์ด ํ์ ์ ์ค๊ณํ ๋ ์ ๋ค๋ฆญ ํ์ ์ ๊ณ ๋ คํด๋ณด๋ ๊ฒ์ด ์ข๋ค.
์์ ์ฝ๋
์ ๋ค๋ฆญ ํ์
์ ์ฉ ์ ์ฝ๋
class Stack {
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private Object[] elements;
private int size = 0;
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);
}
}
}
class Main {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push("Hello");
stack.push("Ogu");
while (!stack.isEmpty()) {
System.out.println(stack.pop());
}
}
}
์์ ๊ฐ์ Stack ํด๋์ค๊ฐ ์๋ ๊ฒฝ์ฐ ์ ๋ค๋ฆญ์ ์ ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ์์ฒ๋ผ ์ ๋ค๋ฆญ ์ฝ๋๋ฅผ ์ ์ฉํ๋๋ผ๋ ๊ธฐ์กด์ ์ฌ์ฉํ๋ ํด๋ผ์ด์ธํธ ์ฝ๋๋ ๋ณ๊ฒฝํ ํ์๊ฐ ์๋ค.(๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํ์ง๋ง Raw Type์ผ๋ก ์ฌ์ฉํ ์๋ ์์ด ์๋ฌ๋ ๋ฐ์ํ์ง ์์)
์ ๋ค๋ฆญ ํ์
์ ์ฉ ์ฝ๋
class Stack<E> {
private E[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY]; // ๊ฒฝ๊ณ ๋ฐ์, Unchecked cast: 'java.lang.Object[]' to 'E[]'
}
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);
}
}
}
class Main {
public static void main(String[] args) {
// ๊ฒฝ๊ณ ๋ฐ์, Raw use of parameterized class 'Stack'
Stack stack = new Stack();
stack.push("Hello");
stack.push("Ogu");
while (!stack.isEmpty()) {
System.out.println(stack.pop());
}
}
}
ํด๋ผ์ด์ธํธ(Main) ์ฝ๋์ ๊ฒฝ๊ณ ๋ ๋ฐ์ํ์ง๋ง, ์์ฑ์์์ ๋ฐ์ํ๋ ๋น๊ฒ์ฌ ๊ฒฝ๊ณ ๋ฅผ ์ ๊ฑฐํ๊ธฐ ์ํด @SuppressWarnings("unchecked")
์ด๋
ธํ
์ด์
์ ์ถ๊ฐํ ์ ์๋ค.
@SuppressWarnings("unchecked")
์ด๋
ธํ
์ด์
์ถ๊ฐ
@SuppressWarnings("unchecked")
์ด๋
ธํ
์ด์
์ถ๊ฐ์์ฑ์์ @SuppressWarnings("unchecked")
์ด๋
ธํ
์ด์
์ถ๊ฐํ๋ ๋ฐฉ๋ฒ๊ณผ ํ๋์ elements
๋ฅผ Object ๋ฐฐ์ด๋ก ์ ์ธํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
๋ ๋ฐฉ๋ฒ์ ์ ๋ต์ด ์๋ ๊ฒ์ ์๋๋ฉฐ ์ฅ/๋จ์ ์ด ์๊ธฐ ๋๋ฌธ์ ์ํฉ์ ๋ง๊ฒ ์ฌ์ฉํ๋ฉด ๋๋ค.
์์ฑ์์
@SuppressWarnings("unchecked")
์ด๋ ธํ ์ด์ ์ถ๊ฐ
class Stack<E> {
// ...
// ๋ฉ์๋์ ์ ์ฉ
@SuppressWarnings("unchecked")
public Stack() {
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}
// ...
}
์ปดํ์ผ๋ฌ์์ ํ์ ์์ ํ์ง ์ฆ๋ช ํ ์ ์์ง๋ง, ๊ฐ๋ฐ์๋ ํ์ ์์ ํ๋ค๊ณ ํ์ ํ ์ ์์ ๋ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค. ์ ์ฝ๋์์๋ ์๋์ ์กฐ๊ฑด์ ๋ง์กฑํ๊ธฐ ๋๋ฌธ์ ํ์ ์์ ํ๋ค๊ณ ํ์ ํ ์ ์๋ค.
elements
๊ฐ private ํ๋์ ์ ์ฅ๋จ: ํด๋ผ์ด์ธํธ์์ ์ง์ ์ ๊ทผ ๋ถ๊ฐํด๋ผ์ด์ธํธ๋ ๋ค๋ฅธ ๋ฉ์๋์ ์ ๋ฌ๋๋ ์ผ์ด ์์:
elements
๋ฐฐ์ด์ ๋ฐํํ์ง ์์ ํด๋ผ์ด์ธํธ๊ฐ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ์ ๊ทผํ ์ ์์push
๋ฉ์๋์์elements
๋ฐฐ์ด์ ์ ์ฅ๋๋ ํ์ ์E
๋ก ์ง์ :elements
๋ฐฐ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ์ ์ผํ ๋ฉ์๋์ด๋ฉฐ,elements
๋ฐฐ์ด์ ์ ์ฅ๋๋ ์์์ ํ์ ์ดE
๋ก ํ์ ๋์ด ์์
์ด ๋ฐฉ๋ฒ์ ๊ฐ๋
์ฑ์ด ๋ ์ข์ผ๋ฉฐ, elements
๋ฐฐ์ด ์์ฑ ์ ํ ๋ฒ๋ง ํ๋ณํ์ ํ๊ธฐ ๋๋ฌธ์ ๊ฐํธํ๋ค.
ํ์ง๋ง ๋ฐฐ์ด์ ๋ฐํ์ ํ์
์ด ์ปดํ์ผํ์ ํ์
๊ณผ ๋ฌ๋ผ์ง๊ธฐ ๋๋ฌธ์(Generic Type Erasure) ํ ์ค์ผ์ด ๋ฐ์ํ ์ ์๋ค.(์ ์ฝ๋์์ ๋ฐ์ํ์ง ์์)
** ํ ์ค์ผ(Heap Pollution): JVM ํ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ์ค์ผ์ด ๋ ์ํ, ์ ๋ค๋ฆญ์์์ ํ ์ค์ผ์ ์ ์ฉ๋ ์ ๋ค๋ฆญ ํ์ ๊ณผ ๋ค๋ฅธ ํ์ ์ ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ๋ ๋ฐ์ํ๋ ๊ฒ์ ์๋ฏธ
ํ๋์
elements
๋ฅผ Object ๋ฐฐ์ด๋ก ์ ์ธ
class Stack<E> {
private Object[] elements; // E -> Object ๋ณ๊ฒฝ
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]; // Object ๋ฐฐ์ด์ด๊ธฐ ๋๋ฌธ์ ํ๋ณํ ์ถ๊ฐ
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 ํ์
์ผ๋ก ๋ณํํ๊ธฐ ๋๋ฌธ์ pop()
์์ ํ ๋ณํ์ด ํ์ํ๋ฐ, ์ด๋๋ @SuppressWarnings("unchecked")
์ด๋
ธํ
์ด์
์ ์ถ๊ฐํ์ฌ ๊ฒฝ๊ณ ๋ฅผ ์จ๊ธธ ์ ์๋ค.
์ด ๊ฒฝ์ฐ์๋ ์์ ํ ์ด์ ๋ ์์ ๋์ผํ๋ค.
์ด ๋ฐฉ๋ฒ์ ํ๋ณํ์ ํ๋ ๋ถ๋ถ์ด ๋ง์ ์ง ์ ์์ด ๊ฐ๋
์ฑ์ด ๋จ์ด์ง๊ณ , elements
๋ฐฐ์ด ์์ฑ ์ ๋งค๋ฒ ํ๋ณํ์ ํด์ผํ๊ธฐ ๋๋ฌธ์ ๋ฒ๊ฑฐ๋กญ๋ค.
ํ์ง๋ง ๊ทธ๋งํผ ํ ๋ณํ์ ๋ฒ์๊ฐ ์ต์ํ๋๊ณ ํ ์ค์ผ์ ์์น๋ ์ต์ํ๋๊ธฐ ๋๋ฌธ์ ํ ์ค์ผ์ ๋ํด ๋ ์์ ํ๋ค.
์ ํ์ด ํ์ํ ์ ๋ค๋ฆญ
์ ๋ค๋ฆญํ์ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ ๋งค๊ฐ๋ณ์์ ์๋ฌด๋ฐ ์ ์ฝ์ ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ํ์ ์ ์์ฉํ ์ ์๋ค. ํ์ง๋ง ํ์์ ๋ฐ๋ผ ํน์ ํ์ ๋ง ์์ฉํ๋๋ก ์ํฉ์๋ ์ ํ์ ๋๋ ๊ฒ์ด ์ข๋ค.
// Delayed ํด๋์ค์ ํ์ ํด๋์ค๋ง ์์ฉํ๋๋ก ์ ํ์ ๋์ด ํ์
์์ ์ฑ์ ๋ณด์ฅ
public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
implements BlockingQueue<E> {
// ...
}
Last updated
Was this helpful?