[Effective Java 3/e] 아이템 26 - 로 타입은 사용하지 말라
아이템 26 - 로 타입(raw type)은 사용하지 말라
로 타입 - 타입 매개변수를 전혀 사용하지 않은 것
- List
의 로 타입은 List - 로 타입을 쓰면 제네릭이 안겨주는 안전성과 표현력을 모두 잃게 된다.
컬렉션의 로 타입- 따라 하지 말 것
//Stamp 인스턴스만 취급한다.
private final Collection stamps = ...;
//실수로 동전을 넣는다.
stamps.add(new Coin(...)); //unchecked call 경고를 내뱉는다.
반복자의 로 타입 - 따라 하지 말 것
for (Iterator i = stamps.iterator(); i.hasNext();) {
Stamp stamp = (Stamp) i.next(); //ClassCastException을 던진다.
stamp.cancel();
}
매개변수화된 컬렉션 타입 - 타입 안전성 확보
private final Collection<Stamp> stamps = ...;
- 잘못 된 타입의 인스턴스를 넣으려 하면 컴파일 오류가 발생
잘못된 예 - 모르는 타입의 원소도 받는 로 타입을 사용했다
static int numElementsInCommon(Set s1, Set s2) {
int result = 0;
for (Object o1 : s1)
if (s2.contains(o1))
result++;
return result;
}
비한정적 와일드카드 타입을 사용하라 - 타입 안전하며 유연하다
static int numElementsInCommon(Set<?> s1, Set<?> s2) {...}
로 타입을 써야 하는 예외 상황
- class 리터럴에는 로 타입을 써야 한다.
- 허용 - List.class, String[].class
- 불허용 - List
.class, List<?>.class
- 제네릭 타입에 instanceof 사용
로 타입을 써도 좋은 예 - instanceof 연산자
if (o instaceof Set) { // 로 타입
Set<?> s = (Set<?>) o; // 와일드카드 타입
}
- o의 타입이 Set임을 확인한 다음 와일드카드 타입인 Set<?>로 형변환해야 한다.
- 이는 검사 형변환(checked cast)이므로 컴파일러 경고가 뜨지 않는다.
정리
- 로 타입을 사용하면 런타임에 예외가 일어날 수 있으니 사용하면 안 된다.
- Set
- Set<?>는 모종의 타입 객체만 저장할 수 있는 와일드카드 타입
- Set은 제네릭 타입 시스템에 속하지 않는다.
- Set