타입 안전 이종 컨테이너 패턴

컨테이너 대신 키를 매개변수화한 다음, 컨테이너에 값을 넣거나 뺄 때 매개변수화한 키를 함께 제공하여 제네릭 타입 시스템이 값의 타입이 키와 같음을 보장해주는 설계 패턴 방식

public class Favorites {
    private Map<Class<?>, Object> favorites = new HashMap<>();

    public <T> T getFavorite(Class<T> type) {
        return type.cast(favorites.get(type));
    }
    public <T> void putFavorite(Class<T> type, T instance) {
        favorites.put(Objects.requireNonNull(type), type.cast(instance));
    }
    ...
}
public static void main(String[] args) {
    Favorites f = new Favorites();
    
    f.putFavorite(String.class, "Java");
    f.putFavorite(Integer.class, 0xcafebabe);
    f.putFavorite(Class.class, Favorites.class);
    
    String favoriteString = f.getFavorite(String.class);
    int favoriteInteger = f.getFavorite(Integer.class);
    Class<?> favoriteClass = f.getFavorite(Class.class);
    
    System.out.printf("%s %x %s%n", favoriteString,
            favoriteInteger, favoriteClass.getName());
}

Favorites 클래스의 한계

  1. 클라이언트에서 악의적으로 로 타입을 넘기면 안정성이 깨짐

    f.putFavorite((Class) List.class, "악의적이다");
    // 런타임에 ClassCastException 발생 
    

    → 이를 예방하기 위해 형변환 검사를 추가하자

  2. 실체화 불가 타입에는 사용할 수 없음

    ex) List<String>.class 와 같은 실체화 불가 타입에 사용할 수 없음

    → 이를 해결하기 위해 슈퍼 타입 토근 이라는 방식이 있지만 완벽하지 않음

한정적 타입 토큰

정리