로 타입(raw type) 이란 제네릭 타입에서 타입 매개변수를 전혀 사용하지 않을 때를 말한다.
List<E>의 로 타입은 List이다. 로 타입은 타입 선언에서 제네릭 타입 정보가 전부 지워진 것처럼 동작하는데, 제네릭이 도래하기 전 코드와 호환되로록 하기 위한 궁여지책이라 할 수 있다.
- 로 타입을 사용하면 런타임에 예외가 일어날 수 있으니 사용하면 안됀다.
- 로 타입은 제네릭이 도입하기 이전 코드와의 호환성을 위해 제공될 뿐이다.
- 빠르게 훑어보자면,
Set<Object>는 어떤 타입의 객체도 저장할 수 있는 매개변수화 타입이고,
Set<?>은 모종의 타입 객체만 저장할 수 있는 와일드카드 타입이다.- 이들의 로 타입인 Set은 제네릭 타입 시스템에 속하지 않는다.
Set<Object>와Set<?>은 안전하지만, 로타입인Set은 안전하지 않다.
- 제네릭을 사용하기 시작하면 수많은 경고가 발생한다.
제거하기 어려운 경고도 있지만 할 수 있는 한 모든 비검사 경고를 제거하라. 다이아몬드 연산자(<>) 만으로 해결할 수 있는 경우가 많다.- 비검사 경고는 중요하지 무시하지 말자.
- 모든 비검사 경고는 런타임에 ClassCastException을 일으킬 수 있는 잠재적 가능성을 뜻하니 최선을 다해 제거하라.
- 경고를 없앨 방법을 찾지 못하겠다면, 그 코드가 타입 안전함을 증명하고 간응한 한 범위를 좁혀
@SuppressWarnings("unchecked")어노테이션으로 경고를 숨겨라.- 그런 다음 경고를 숨기기로 한 근거를 주속으로 남겨라.
- 배열과 제네릭에는 매우 다른 타입 규칙이 적용된다.
- 배열은 공변이고 실체화되는 반면, 제네릭은 불공변이고 타입 정보가 저장된다.
- 그 결과 배열은 런타임에는 타입이 안전하지만, 컴파일타임에는 그렇지 않다. 제네릭은 반대다
- 그래서 둘을 섞어 쓰기란 쉽지 않다. 둘을 섞어 쓰다가 컴파일 오류나 경고를 만나면, 가장 먼저 배열을 리스트로 대체하는 방법을 적용해보자.
- 클라이언트에서 직접 형변환해야 하는 타입보다 제네릭 타입이 더 안전하고 쓰기 편하다. 따라서 새로운 타입을 설계할 때는 형변환 없이도 사용할 수 있도록 하라.
- 그렇게 하려면 제네릭 타입으로 만들어야 할 경우가 많다.
- 기존 타입 중 제네릭이었어야 하는게 있다면 제네릭 타입으로 변경하자.
- 기존 클라이언트에는 아무 영향을 주지 않으면서, 새로운 사용자를 훨씬 편하게 해주는 길이다.
- 제네렉 타입과 마찬가지로, 클라이언트에서 입력 매개변수와 반환값을 명시적으로 형변환해야 하는 메서드보다 제네릭 메서드가 더 안전하며 사용하기도 쉽다.
- 타입과 마찬가지로, 메서드도 형변환 없이 사용할 수 있는 편이 좋으며, 많은 경우 그렇게 하려면 제네릭 메서드가 되어야 한다.
- 역시 타입과 마찬가지로, 형변환을 해줘야 하는 기존 메서드는 제네릭하게 만들자.
- 기존 클라이언트는 그대로 둔 채 새로운 사용자의 삶을 훨씬 편하게 만들어줄 것이다.