Java

Effective Java 제 5장 - 제네릭

iksadnorth 2023. 8. 22. 23:04

해당 게시물은 책 'Effective Java'를 참고하고 작성했습니다.

로 타입[List<E>가 아니라 List로만 사용하는 형태]는 절대 사용마라!
컴파일러가 인지하지도 못하고 표현력도 떨어지므로 절대 사용하지 않아야 한다.
자바 측에서 로 타입을 문법적 오류로 규정짓지 않는 이유는 오직 이전 버전과의 호환성 때문이다.

배열보다 리스트를 사용해라!
배열은 컴파일 시점에서 타입 체크를 하지 않고 공변성이 있어서
런타임에 오류를 내놓을 확률이 비교적 크다.

재사용성을 위해 되도록 제네릭 클래스, 메서드를 만들라!
클라이언트가 직접 형변환을 하지 않게 제네릭을 활용하라.

제네릭은 불공변성[List<Child> -> List<Parent>]이기에 한정적 와일드카드[List<? extends Parent>]를 사용해라!
배열과 달리 List<Child>는 List<Parent>로 타입 변환이 이뤄지지 않기 때문에 
한정적 와일드 카드 즉, List<? extends Parent>를 사용해 컴파일러에게 알려줘야 한다.

타입 안전 이종 컨테이너를 고려하라!
다양한 타입을 보유하는 컨테이너를 구현하고 싶다면 다음과 같이 구성하면 된다.

더보기
class TypeSafeContainer<T> {
    private Map<Class<? extends T>, T> map = new HashMap<>();

    void put(Class<? extends T> clazz, T instance) {
        map.put(clazz, instance);
    }

    T get(Class<? extends T> clazz) {
        return clazz.cast(map.get(clazz));
    }
}

TypeSafeContainer<Shape> container = new TypeSafeContainer<>();
container.put(Circle.class, new Circle());
container.put(Rectangle.class, new Rectangle());
container.put(Triangle.class, new Triangle());

Circle circle = container.get(Circle.class);
Rectangle rectangle = container.get(Rectangle.class);
Triangle triangle = container.get(Triangle.class);