아이템 29. 형 안전 다형성 컨테이너를 쓰면 어떨지 따져보라

29. 형 안전 다형성 컨테이너를 쓰면 어떨지 따져보라

// 형 안전 다형성(heterogeneous)컨테이너 패턴
public class Favorites {
    private Map<Class<?>, Object> favroites = new HashMap<Class<?>, Object>();

    public <T> void putFavorite(Class<T> type, T instance) {
        if (type == null)
            throw new NullPointerException("Type is null");
        // before 타입안정성 사라짐
        // favorites.put(type, instance);
        // after 보완코드
        favorites.put(type, type.cast(instance));
    }

    public <T> T getFavorite(Class<T> type) {
        // 타입안정성 복구 - 동적 형변환
        return type.cast(favorites.get(type));
    }
}

형 안전 다형성 컨테이너의 문제점

  1. Class(raw type)를 인자로 넘기면 형이 지정되지 않았기 때문에 형 안정성이 깨질수 있음
    • favorites.put(type, type.cast(instance));등과 같이 Class cast메서드로 커버 가능
  2. 실체화 불가능한 자료형은 쓸수 없음, 예를 들어 List<String>.class는 제너릭 인터페이스 이기 때문에 class가 존재하지 않음
    • 언어 차원에서 지원되지 않기 때문에 실질적인 해결법이 없음
    • 외부 라이브러리 사용 필요

asSubClass

public static Annotation GetAnnotation(AnnotatedElement element, String annotationTypeName){
    Class<?> annotationType = null;
    try{
        annotationType = Class.forName(annotationTypeName);
    }catch(Exception e){
        throw new IllegalArgumentException(e);
    }
    return element.getAnnotation(annotationType.asSubClass(Annotation.class));
}

결론

컨테이너 대신 키를 제네릭으로 만들면 형인자 개수가 고정되는 제약없는 형 안전 다형성 컨테이를 만들 수 있다. 그런경우 Class 객체(자료형 토큰)를 키로 쓰면되며, Column<T>와 같이 직접 구현할 수도 있다.