본문 바로가기
IT/JAVA

Effective Java 2 - 규칙26 - "가능하면 제네릭 자료형으로 만들것"

by 최고영회 2016. 8. 6.
728x90
반응형
SMALL

- 제네릭 자료형은 클라이언트가 형변환을 해야만 사용할 수 있는 자료형보다 안전할 뿐 아니라 사용하기도 쉽다. 
- 새로운 자료형을 설계할 때는 현변환 없이도 사용할 수 있도록 하라.
- 시간 있을때 마다 기존 자료형을 제네릭 자료형으로 변환하라.
- 기존 클라이언트 코드를 깨지 않고도 새로운 사용자에게 더 좋은 API를 제공할 수 있게 될 것이다.

제네릭 자료형을 직접 만드는 것은 까다롭지만 배울만한 가치는 있다.
아래의 source code 를 살펴 보자.

public class Stack { private Object[] elements; private int size; 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 = Array.copyOf(elements, 2*size+1); } } }

위 클래스를 호환성을 유지하면서도 제네릭 자료형을 사용하도록 개선해 보자. 
위 클래스는 stack 에서 꺼낸 객체를 사용하기 전에 형변환을 해야 하는데 실패할 가능성이 있다. 

public class Stack<E> { private E[] elements; private int size; private static final int DEFAULT_INITIAL_CAPACITY = 16; // elemens 배열에는 push(E)를 통해 전달된 E 형의 객체만 저장된다. // 형 안정성을 보장할 수 있다. 배열의 실행시간 자료형은 E[]가 아니라 항상 // Object[] 이다. @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(); Object result = elements[--size]; elements[size] = null; return result; } // isEmpty, ensureCapacity... 는 동일 }

위와 같이 제네릭형으로 만든 Stack 을 사용하는 예제 소스코드를 살펴 보자.

public static void main(String[] args) { Stack<String> stack = new Stack<String>(); for (String arg : args) { stack.push(arg); } while (!stack.isEmpty()) { System.out.println(statck.pop().toUpperCase()); } }

toUpperCase() 를 호출하기 위해 스택에서 꺼낸 객체를 명시적으로 형변환할 필요가 없다. 
자동으로 생성된 형변환 코드는 항상 성공적으로 실행 될 것이다.


728x90
반응형
LIST