이펙티브 자바 - 5장 제네릭
raw type은 사용하지 마라
raw type?
타입 매개변수 <E> 가 있을때 제네릭 클랫, 제네릭 인터페이스라 한다.
List<E> 이걸 제네릭 타입이라고 한다. 제네릭 타입을 정의 할때 raw type 도 정의 되는데
여기선 List 가 raw type 이다. 매개변수를 쓰지 않고 사용한 경우
이것은 제네릭이 도입 되기전의 호환성을 위해 쓸 수 있는것
왜 사용하면 안될까?
컴파일단에서 에러를 발견하지 못한다.
런타임에서 오류가나서 컴파일러의 검사를 사용하지 못한다.
List arrayList = new ArrayList();
로 제네틱 타입이 없는 경우를 만들었을때
arrayList.add("Test") 를 넣으면 컴파일러가 걸러내지 못한다.
타입 세이프가 없는 셈이된다.
반면에,
List<?> arrayList = new ArrayLsit() 로 와일드 카드를 사용해 만들었을경우에는
arrayList.add("Test") 를 썻을때 컴파일 에러가 발생한다.
비검사 경고를 제거하라
비검사 경고(ex. warning: [unchecked] unchecked ...)를 제거할수록 타입 안정성이 높아진다고 볼 수 있다.
만약 타입 안정성이 확실한데 컴파일러의 경고를 없애고 싶다면 @SuppressWarnings("unchecked")를 사용하자.
@SuppressWarning 은 가능한 좁은 범위로 만든자
배열보다는 리스트를 사용하라.
배열과 리스트의 차이는
배열은 하위 타입도 받을 수 있어서 (ex. Object 로 선언된 변수에서 Long 타입도 넣을수있다.)
데이터 삽입 에러가 런타임에 나지만,
리스트를 사용하면 컴파일 에러가 나서 바로 찾을 수 있다.
배열은 런타임까지 타입 정보를 가지고 있지만,
리스트는 런타임이 타입 정보를 없앤다.
이왕이면 제네릭 타입으로 만들라.
클라이언트에서 직접 형변환을 하지 말고
이왕이면 제네릭 타입으로 생성해라
제네릭 타입이 훨씬 안전하다.
이왕이면 제네릭 메서드로 만들라.
같은이유로 매개변수와 리턴값을 형변환 하는 것보다
제네릭 타입으로 메서드를 만드는게 좋다.
한정적 와일드카드를 사용해 API 유연성을 높여라
제네릭의 매개변수 타입은 불공변이다.
즉 한 타입만 허용한다.
그러다보니, 이미지 처럼 <Number> 타입에 <Integer>를 넣었을때 에러가 발생하는 경우가 있다.
이건 한정적 와일드 카드를 사용해 받을 수 있다.
하위 타입도 받을 수 있게 된다.
제네릭과 가변인수를 함께 쓸 때는 신중해라
제네릭 변수에 가변인수를 저장하면 안전하지 않다.