item 29 Jung inchul - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

Effective Java 3e μ•„μ΄ν…œ 29λ₯Ό μš”μ•½ν•œ λ‚΄μš© μž…λ‹ˆλ‹€.

JDKκ°€ μ œκ³΅ν•˜λŠ” μ œλ„€λ¦­ νƒ€μž…κ³Ό λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 일은 일반적으둜 μ‰¬μš΄ νŽΈμ΄μ§€λ§Œ, μ œλ„€λ¦­ νƒ€μž…μ„ μƒˆλ‘œ λ§Œλ“œλŠ” 일은 쑰금 더 μ–΄λ ΅λ‹€.

public class Stack {
    private Object[] elements;
    ...

    public Stack() {
    elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
    ...
    }

    public Object pop() {
    if (size == 0)
        throw new EmptyStackException();
    Object result = elements[--size];
    ...
    }
    ...
}

μœ„ Stack 클래슀λ₯Ό μ œλ„€λ¦­μœΌλ‘œ λ§Œλ“€μ–΄ 보자

public class Stack<E> {
    private E[] elements;
    ...

    public Stack() {
    elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(E e) {
    ...
    }

    public E pop() {
    if (size == 0)
        throw new EmptyStackException();
    E result = elements[--size];
    ...
    }
    ...
}

그러면 μ•„λž˜μ™€ 같은 κ²½κ³  λ©”μ‹œμ§€λ₯Ό 확인할 수 μžˆμ„ 것이닀.

Stack.java:8: warning: [unchecked] unchecked cast
found: Object[], required: E[]
        elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
                        ^

문제의 λ°°μ—΄ elementsλŠ” private ν•„λ“œμ— μ €μž₯되고 ν΄λΌμ΄μ–ΈνŠΈλ‘œ λ°˜ν™˜λ˜κ±°λ‚˜ λ‹€λ₯Έ λ©”μ„œλ“œμ— μ „λ‹¬λ˜λŠ” 일이 μ „ν˜€ μ—†λ‹€. push λ©”μ„œλ“œλ₯Ό 톡해 배열에 μ €μž₯λ˜λŠ” μ›μ†Œμ˜ νƒ€μž…μ€ 항상 Eλ‹€. λ”°λΌμ„œ 이 비검사 ν˜•λ³€ν™˜μ€ ν™•μ‹€νžˆ μ•ˆμ „ν•˜λ‹€.

비검사 ν˜•λ³€ν™˜μ΄λž€? κ²€μ‚¬ν•˜μ§€ μ•Šλ‹€κ³  ν˜•λ³€ν™˜ν•˜λŠ” 경우λ₯Ό λ§ν•œλ‹€. μœ„μ™€ 같이 Eκ°€ 무슨 νƒ€μž…μΈμ§€ μ•Œ 수 μ—†μ–΄μ„œ μ»΄νŒŒμΌλŸ¬κ°€ λŸ°νƒ€μž„μ—λ„ μ•ˆμ „ν• μ§€ μ•Œ 수 μ—†λ‹€λŠ” κ²½κ³ λ₯Ό 보여주고 μžˆλ‹€. μ œλ„€λ¦­μ€ 싀체화 λΆˆκ°€ νƒ€μž…μ΄λ―€λ‘œ λŸ°νƒ€μž„μ—μ„œλŠ” νƒ€μž…μ— λŒ€ν•œ 정보가 μ†Œκ±°λ˜κΈ° λ•Œλ¬Έμ΄λ‹€.

비검사 ν˜•λ³€ν™˜μ΄ μ•ˆμ „ν•¨μ„ 직접 증λͺ… ν–ˆλ‹€λ©΄ λ²”μœ„λ₯Ό μ΅œμ†Œλ‘œ μ’ν˜€ @SuppressWarnings μ—λ„ˆν…Œμ΄μ…˜μœΌλ‘œ ν•΄λ‹Ή κ²½κ³ λ₯Ό μˆ¨κΈ΄λ‹€.

// λ°°μ—΄ elementsλŠ” push(E)둜 λ„˜μ–΄μ˜¨ E μΈμŠ€ν„΄μŠ€λ§Œ λ‹΄λŠ”λ‹€.
// λ”°λΌμ„œ νƒ€μž… μ•ˆμ „μ„±μ„ 보μž₯ν•˜μ§€λ§Œ,
// 이 λ°°μ—΄μ˜ λŸ°νƒ€μž„ νƒ€μž…μ€ E[] κ°€ μ•„λ‹Œ Object[]λ‹€!
@SuppressWarnings("unckecked")
public Stack() {
    elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];
}

μ œλ„€λ¦­ λ°°μ—΄ 생성 였λ₯˜λ₯Ό ν•΄κ²°ν•˜λŠ” 두 번째 방법은 elements ν•„λ“œμ˜ νƒ€μž…μ„ E[]μ—μ„œ Object[]둜 λ°”κΎΈλŠ” 것이닀.

EλŠ” 싀체화 λΆˆκ°€ νƒ€μž…μ΄λ―€λ‘œ μ»΄νŒŒμΌλŸ¬λŠ” λŸ°νƒ€μž„μ— μ΄λ€„μ§€λŠ” ν˜•λ³€ν™˜μ΄ μ•ˆμ „ν•œμ§€ 증λͺ…ν•  방법이 μ—†λ‹€. μ΄λ²ˆμ—λ„ μš°λ¦¬κ°€ 직접 증λͺ…ν•˜κ³  κ²½κ³ λ₯Ό 숨길 수 μžˆλ‹€.

public E pop() {
    if (size == 0)
        throw new EmptyStackException();

    // pushμ—μ„œ E νƒ€μž…λ§Œ ν—ˆμš©ν•˜λ―€λ‘œ 이 ν˜•λ³€ν™˜μ€ μ•ˆμ „ν•˜λ‹€.
    @SuppressWarnings("unckecked") E result = (E) elements[--size];
    ...
}

νƒ€μž… λ§€κ°œλ³€μˆ˜μ— μ œμ•½μ„ λ‘λŠ” μ œλ„€λ¦­ νƒ€μž…λ„ μžˆλ‹€.

java.util.concurrent.DelayQueueλ₯Ό 보면 확인할 수 μžˆλ‹€.

class DelayQueue<E extends Delayed> implements BlockingQueue<E>

μ΄λ ‡κ²Œ ν•˜μ—¬ DelayQueue μžμ‹ κ³Ό DelayQueueλ₯Ό μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈλŠ” DelayQueue의 μ›μ†Œμ—μ„œ (ν˜•λ³€ν™˜ 없이) κ³§λ°”λ‘œ Delayed 클래슀의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

정리

ν΄λΌμ΄μ–ΈνŠΈμ—μ„œ 직접 ν˜•λ³€ν™˜ν•΄μ•Ό ν•˜λŠ” νƒ€μž…λ³΄λ‹€ μ œλ„€λ¦­ νƒ€μž…μ΄ 더 μ•ˆμ „ν•˜κ³  μ“°κΈ° νŽΈν•˜λ‹€. κ·ΈλŸ¬λ‹ˆ μƒˆλ‘œμš΄ νƒ€μž…μ„ 섀계할 λ•ŒλŠ” ν˜•λ³€ν™˜ 없이도 μ‚¬μš©ν•  수 μžˆλ„λ‘ ν•˜λΌ. κΈ°μ‘΄ νƒ€μž… 쀑 μ œλ„€λ¦­μ΄μ—ˆμ–΄μ•Ό ν•˜λŠ” 게 μžˆλ‹€λ©΄ μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ³€κ²½ν•˜μž.

좜처