아이템 26부터 제네릭에 대한 내용이다.
로 타입이란 타입 매개변수가 없는 제네릭 타입으로 List를 예로 들 수 있다.
List rawList = new ArrayList(); // 로 타입 리스트
List<String> strings = new ArrayList<>(); // 문자열을 담는 리스트
List<Integer> integers = new ArrayList<>(); // 정수를 담는 리스트
rawList.add(1);
rawList.add(1.1);
rawList.add("raw");
rawList.add('r');
strings.add(1); // 컴파일 에러
로 타입은 Object를 넣을 수 있어 어떤 객체도 담을 수 있다. 그래서 문제가 되는데 예상치 못하게 넣지 말아야 할 객체를 넣었다면 형 변환 런타임 오류가 발생할 수 있다.
▶ List vs List<Object>
둘 다 Object를 담는 리스트로 어떤 타입이든 담을 수 있는 리스트지만 엄연히 서로 다른 리스트이다.
List는 어떤 타입을 담을지 명시를 안 한 것이고, List<Object>는 모든 타입을 허용한다는 의미이다.
또한 List<String>은 List의 하위 타입이지만, List<Object>의 하위 타입은 아니다.
public static void main(String[] args) {
List list = new ArrayList(); // 로 타입 리스트
List<String> strings = new ArrayList<>(); // 문자열을 담는 리스트
List<Integer> integers = new ArrayList<>(); // 정수를 담는 리스트
funRawList(list);
funRawList(strings);
funRawList(integers);
funObjectList(list);
funObjectList(strings); // 컴파일 에러
funObjectList(integers); // 컴파일 에러
funWildCard(list);
funWildCard(strings);
funWildCard(integers);
}
static void funRawList(List list) {
}
static void funObjectList(List<Object> list) {
}
static void funWildCard(List<?> list) {
}
로 타입 매개변수 자리에는 어떤 List라도 들어갈 수 있으나, List<Object> 자리에는 List나 List<Obejct> 타입만 가능하다.
참고로 매개변수 제네릭 타입이 명확하진 않을 땐 와일드카드 <?>를 사용하면 된다
▶ 로 타입을 사용하는 예
- class 리터럴
- ex) List.class (O)
- ex) List<String>.class (X)
- instanceof 연산자
- list instanceof List (O)
- list instanceof List<String> (X)
결국 로 타입을 쓰지 말아야 하는 이유는 안전성 이유인데 자바에서 허용하는 이유는 과거 코드의 호환성이다.
'Java > Effective Java' 카테고리의 다른 글
[아이템 50] 적시에 방어적 복사본을 만들라 (0) | 2022.02.15 |
---|---|
[아이템 49] 매개변수가 유효한지 검사하라 (0) | 2022.02.14 |
[아이템 8] finalizer와 cleaner 사용을 피하라 (0) | 2022.01.01 |
[아이템 7] 다 쓴 객체 참조를 해제하라 (0) | 2021.12.23 |
[아이템 6] 불필요한 객체 생성을 피하라 (0) | 2021.12.21 |
댓글