로 타입은 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않을 때를 말한다.
List list = new ArrayList();
위와 같은 형태를 말한다.
로 타입의 문제점
- 타입 안정성과 표현력을 확보할 수 없다.
- 문제점이 컴파일 시에 걸러내지 못하고 런타임에 예외가 발생한다.
따라서 매개 타입을 선언해서 타입 안정성과 표현력을 가져가야 한다.
List와 List<Object>의 차이점
임의의 객체 타입을 받는다는 표현을 한 것이고 두 동작은 같을 것이다. 대신에 컴파일러가 이 사실을 아냐 모르냐에 차이점이 있다.
Object 의 매개 타입은 모든 타입을 허용한다는 표현을 한것이고 컴파일러에게 전달한다. 이로 인해 List<Object>은 하위 타입 규칙과 타입 안정성을 모두 지킬 수 있게 된다.
매개 변수 타입에서 사용된다면
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
add(list);
}
private static void add(List list) {
list.forEach(System.out::println);
}
}
List 를 매개변수로 받는 메서드에서 List<String> 타입을 넘긴다. List<String> 은 List와 같은 로 타입의 하위 타입이기 때문에 컴파일 에러는 나지 않고 List<String> 값만 넣어준다면 런타임에도 문제가 없을 것이다.
그러면 List<Object> 타입을 매개변수로 받는다면?
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
add(list);
}
private static void add(List<Object> list) {
list.forEach(System.out::println);
}
}
List<String> 은 List<Object> 의 하위 타입이 아니기 때문에 컴파일 에러가 발생한다.
따라서 타입의 안정성을 가지려면 매개 타입을 사용하는 것을 권장한다.
와일드 카드
제네릭 타입을 쓰고 싶지만 실제 타입 매개변수가 무엇인지 신경 쓰고 싶지 않다면 비한정적인 와일드 카드 <?> 를 사용하자.
어떤 타입이라도 담을 수 있는 가장 범용적인 매개변수화 타입이다.
로타입 컬렉션에는 아무 타입의 원소를 넣을 수 있는 반면 비한정적 와일드 카드에는 null 이외에는 아무것도 넣을 수 없다. 넣는 다면 컴파일 에러가 날 것이다.
반드시 형변환 검사가 필요하다.
public static void add(List<?> list){
for (Object o : list) {
if (o instanceof String) {
//....
}
}
}
Row Type을 사용해도 되는 경우
- class 리터럴에는 로 타입을 사용한다.
- MemberService.class → o
- MemberService<Member> → x
- instanceof에 사용해도 된다.
- 런타임시 제네릭 정보가 제거되므로 instanceof연산자는 비한정적 와일드카드 타입 이외의 매개변수화 타입에는 로 타입을 사용해도 동일하게 동작한다.
'Book > Effective Java' 카테고리의 다른 글
[Item 30] 이왕이면 제네릭 메서드로 만들라 (0) | 2022.08.30 |
---|---|
[Item 29] 이왕이면 제네릭 타입으로 만들라 (0) | 2022.08.18 |
[Item 28] 배열보다는 리스트를 사용하라 (0) | 2022.08.18 |
[Item 27] 비검사 경고를 제거하라 (0) | 2022.08.06 |
[Item 25] 톱레벨 클래스는 한 파일에 하나만 담으라 (0) | 2022.08.05 |
[Item 24] 멤버 클래스는 되도록 static 으로 만들라 (0) | 2022.07.27 |
[Item 23] 태그 달린 클래스보다 클래스 계층구조를 활용하라 (0) | 2022.07.27 |
[Item 22] 인터페이스는 타입을 정의하는 용도로만 사용하라 (0) | 2022.07.26 |