초보개발자 긍.응.성
(이펙티브 자바 3) 26. 로 타입은 사용하지 말라 본문
반응형
용어
- 제네릭 클래스 : 클래스의 선언에 타입 매개변수가 쓰인 클래스
- 제네릭 인터페이스 : 인터페이스의 선언에 타입 매개변수가 쓰인 인터페이스
- 제네릭 타입 : 제네릭 클래스와 제네릭 인터페이스를 통틀어 제네릭이라고 부른다
- 매개변수화 타입 (parameterized type) : 제네릭 타입에 실제 매개변수가 함께 선언된 타입
- 로 타입 (raw type) : 제네릭 타입에서 타입 매개변수를 사용하지 않을 때의 타입
예를 들어 매개변수화 타입이 List <String>이라면
실제 타입 매개변수는 String
이며 로 타입은 List
이다.
제네릭 타입을 하나 정의하면 그에 딸린 로 타입(raw type)도 함께 정의된다.
로 타입의 사용
- 제네릭 대신 로 타입을 사용해도 동작을 하지만 좋은 예가 아니다 (하위 호환성을 위해 지원하고 있다).
- 로 타입을 사용하면 컴파일 시 타입에 대한 오류를 잡아주지 못한다.
- 로 타입은 컴파일러에게 사용하는 타입에 대한 정보를 전달하지 않기에 runtime 예외를 통해 문제를 확인하게 된다.
- 로 타입 사용시 제네릭이 안겨주는 안전성과 표현력을 모두 읽게 된다.
public class RawTypeTest {
public static void main(String[] args) {
List dogs = new LinkedList(); // 로 타입으로 컬렉션 선언
dogs.add(new Cat()); // "unchecked call" 경고
for (Iterator i = dogs.iterator(); i.hasNext(); ) {
Dog dog = (Dog) i.next(); // ClassCastExecption을 던진다.
dog.bark("Hello world!");
}
}
}
매개변수화 타입
- 로 타입의 문제점은 매개변수화된 타입을 사용하여 예방할 수 있다.
- 매개변수화 타입의 사용은 컴파일러에게 타입의 정보를 전달 컴파일 시 오류를 일으켜 잘못된 원인을 정확하게 알려준다.
로 타입과 <Object>의 차이
List와 List
List와 같은 로 타입은 사용해서는 안 되나, List
728x90
비한정적 와일드카드 타입(unbounded wildcard type)
제네릭 타입을 쓰고 싶지만 실제 타입 매개변수가 무엇인지 신경 쓰고 싶지 않을 때 물음표(?)를 사용하여 비한정적 와일드카드 타입으로 사용하라.
와일드카드를 사용하면 어떤 타입이라도 담을 수 있는 가장 범용적인 매개변수화 타입을 만들 수 있다.
로 타입과 비한정적 와일드카드의 차이
Set과 Set<?>의 차이를 예로 들어보자.
간단히 와일드카드 타입은 안전하고, 로 타입은 안전하지 않다.
로 타입 컬렉션에는 아무 원소나 넣을 수 있으니 타입 불변식을 훼손하기 쉽다.
Collection <?>에는 null 외에는 어떤 원소를 넣을 수 없다. 다른 원소를 넣으려 하면 컴파일할 때 다음의 오류 메시지를 보게 될 것이다(컬렉션의 타입 불변식을 훼손하지 못하게 막은 것이다).
로 타입 사용의 예외
1. class 리터럴에는 로 타입을 써야 한다.
- 자바 명세는 class 리터럴에 매개변수화 타입을 사용하지 못하게 했다.
- List.class, String[].class. int.class는 허용하고 List.class와 List<?>.class는 허용하지 않는다.
2. instance of 연산자
- 런타임에는 제네릭 타입 정보가 지워지므로 instanceof 연산자는 비한정적 와일드카드 타입 이외의 매개변수화 타입에는 적용할 수 없다. 그렇기에 로 타입을 이용한다.
if (o instaceof Set) { Set<?> s = (Set<?>)o; ... }
o의 타입이 Set임을 확인한 다음 와일드카드 타입인 Set<?>로 형변환해야한다. 이는 검사 형변환(checked cast)이므로 컴파일러 경고가 뜨지 않는다.
정리
로 타입을 사용하면 런타임에 예외가 일어날 수 있으니 사용하면 안된다. 매개변수화 타입과 와일드카드 타입을 활용하도록 하자.
반응형
'책 정리 > 이펙티브 자바 3' 카테고리의 다른 글
(이펙티브 자바 3) 6장 열거 타입과 애너테이션 정리 (0) | 2020.11.27 |
---|---|
(이펙티브 자바 3) 5장 제네릭 정리 (0) | 2020.11.25 |
(이펙티브 자바 3) 28. 배열보다는 리스트를 사용하라 (0) | 2020.11.23 |
(이펙티브 자바 3) 27. 비검사 경고를 제거하라 (0) | 2020.11.10 |
(이펙티브 자바 3) 25. 톱레벨 클래스는 한 파일에 하나만 담으라 (0) | 2020.11.01 |
(이펙티브 자바 3) 24. - 멤버 클래스는 되도록 static으로 만들라 (0) | 2020.10.28 |
(이펙티브 자바 3) 23. 태그 달린 클래스보다는 클래스 계층구조를 활용하라 (0) | 2020.10.27 |
(이펙티브 자바 3) 22. 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2020.10.22 |
Comments