본문 바로가기

1_스터디

[EffectiveJava] ITEM 29. 이왕이면 제네릭 타입으로 만들라

반응형

 제네릭 타입

배열을 사용하는 코드는 제네릭으로 변환을 고려 해야 한다.

클라이언트단 (소스) 에서 직접 형변환을 해줘야하는 것 보다 제네릭 으로 사용하는 것이 안정성이 높다.

샘플코드
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);
    }


 
Object 를 제네릭으로 변경
 
 
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;
    }
    
    ... // isEmpty와 ensureCapacity 메서드는 그대로다.
}
 
 
위 코드는 아래 부분에서 오류가 발생한다. E와 같은 실체화 불가 타입으로는 배열을 생성 할 수 없다.
 
elements = new E[DEFAULT_INITIAL_CAPACITY];
 
 
이렇게 배열을 사용하는 코드를 제네릭으로 만들려 할 때 해결책은 두 가지
 
  • 1. 제네릭 배열 생성을 금지하는 제약을 대놓고 우회하는 방법이다.
    - Object 배열을 생성한 다음 제네릭 배열로 형변환
elements = (E[]) new Object[DEFAULT_INITIAL_CAPACITY];

 

  • 2. elements 필드의 타입을 E[]에서 Object[]로 변환
E result = elements[--size]; E result = (E) elements[--size];
 
1, 2번 방법 모두 가능하나 첫번째가 가독성이 좋고 변경 범위도 좁다
 
 
핵심정리
 
  • 클라이언트에서 직접 형번환해야 하는 타입 보다 제네릭 타입이 더 안전하고 쓰기 편함.
  • 형 변환 없이 사용하게 하려면 제네릭 타입으로 만들어야 할 경우가 많음
  • 제네릭 타입으로 변경시 기존 클라이언트에는 영향이 없고 새로운 사용자를 편하게 해줌
반응형