우선 용어정의 부터 하자.
용어 | 사용 예 |
매개화 변수타입(Parameterized type) | List<String> |
실 타입 매개변수(Actual type parameter) | String |
제네릭 타입(Generic type) | List<E> |
형식 타입 매개변수(Formal type parameter) | E |
언바운드 와일드 카드 타입 (Unbounded wildcard type) |
List<?> |
원천 타입(Raw type) | List |
바운드 타입 매개변수 (Bounded type parameter) |
<E extends Number> |
재귀적 타입 바운드(Recursive type bound) | <T extends Comparable<T>> |
바운드 와일드 카드 타입 (Bounded wildcard type) |
List<? extends Number> |
제네릭 메소드(Generic method) | static <E> List<E> asList(E[] a) |
타입 토큰(Type token) | String.class |
하나 이상의 타입 매개 변수를 선언하고 있는 클래스나 인터페이스를 제네릭 클래스, 또는 제네릭 인터페이스라고 부른다. 각 제네릭 타입에서는 매개변수화 타입들을 정의한다.
정의 하는 법은 클래스나 인터페이스 이름 다음에 <> 를 사용해서 매개변수들을 나타내는데. 실 타입 매개변수들은 제네릭 타입의 형식 타입 매개변수와 각각 대응된다.
각 제네릭 타입에서는 raw 타입을 정의하는데 원천 타입이란 실 타입 매개변수가 없이 사용되는 제네릭 타입 이름을 말한다. (ex - List 이렇게)
이 경우 타입 매개변수를 주지 않고 커렉션 타입이나 다른 제네릭 타입을 사용할 수 있지만 그렇게 해서는 안된다. 왜냐면 원천 타입을 사용하면 제네릭의 장점인 타입 안전과 표현력 모두를 포기하는 것이기 때문이다.
이걸 막지 않은 이유는 호환성 때문인데 새 코드에서는 되도록 원천 타입을 사용해선 안된다.
간단한 예로 List와 같은 원천 타입을 ㅅ용하면 타입의 안정성을 상실하지만 List<Object>과 같은 매개변수 타입을 사용하면 그렇지 않다.
향후에 작성하는 새 코드에는 원천 타입을 사용하지 않는다는 규칙에도 두가지 예외가 있는데 런타임 시에는 제네릭 타입의 정보가 없어진다는 것 때문에 가능하다.
첫 번째로 원천 타입은 클래스 리터럴의 형태로 사용해야 한다. 자바 명세서에 보면 원천 타입을 매겨변수화 타입과 사용할 수 없다. 즉 String[].class, int.class는 모두 적법하지만 , List<String>.class와 List<?>.class는 허용되지 않는다.
두 번째로 instanceof 연산자와 관련된 것이다. 제네릭 타입의 정보는 런타임 시에 없어지므로 언바운드 와일드 카드 타이이 아닌 다른 매개변수화 타입에 대해 instanceof 연산자를 사용할 수 없다.
'개발 이야기 > Effective Java' 카테고리의 다른 글
Item 21. 전략을 표현할 때 함수 객체를 사용하자. (0) | 2010.03.22 |
---|---|
Item 22. static 맴버 클래스를 많이 사용하자. (0) | 2010.03.22 |
Item 24. 컴파일 경고 메시지가 없게 하자. (0) | 2010.03.22 |
Item 10. toString 메소드는 항상 오버라이드 하자. (0) | 2010.03.11 |
Item 9. equals 메소드를 오버라이드 할 때는 hashcode 메소드도 항상 같이 오버라이드 하자. (0) | 2010.03.11 |