Book/Effective Java

[Item 33] 타입 안전 이종 컨테이너를 고려하라

kkkkkkkkkkkk 2022. 9. 2. 01:32

class 리터럴의 타입은 Class가 아닌 Class<T> 다.

  • String.class 는 Class<String>
  • Integer.class 는 Class<Integer>

 

컴파일타임 타입 정보와 런타임 타입 정보를 알아내기 위해 메서드들이 주고 받는 class 리터럴을 타입 토큰(type token) 이라 한다.

 

 

 

타입 안전 이종 컨테이너 패턴(type safe heterogeneous container pattern)

  • 컨테이너 대신 키를 매개변수화한 다음, 컨테이너에 값을 넣거나 뺄 때 매개변수화한 키를 함계 제공 하는 패턴

 

 

이종 컨테이너 패턴 예제 코드

 

public class Favorites {
    public <T> void putFavorites(Class<T> type, T instance);
    public <T> T getFavorites(Class<T> type);
}

 

키가 매개변수화되었다는 점만 빼면 일반 맵 처럼 보인다. 클라이언트는 즐겨찾기를 저장하거나 얻어올 때 Class 객체만 알려주면 된다.

 

public static void main(String[] args) {
    Favorites favorites = new Favorites();

    favorites.putFavorites(String.class, "java");
    favorites.putFavorites(Integer.class, 100);
    favorites.putFavorites(Class.class, Favorites.class);

    String string = favorites.getFavorites(String.class);
    Integer integer = favorites.getFavorites(Integer.class);
    Favorites favorites1 = favorites.getFavorites(Favorites.class);
}

 

이종 컨테이너 패턴을 적용한 Favorites 인스턴스는 타입 안전하다.

 

 

이종 컨테이너 패턴 예제 코드 구현

 

public class Favorites {

    private Map<Class<?>, Object> favorites = new HashMap<>();

    public <T> void putFavorites(Class<T> type, T instance) {
        favorites.put(Objects.requireNonNull(type), type.cast(instance));
    }

    public <T> T getFavorites(Class<T> type) {
        return type.cast(favorites.get(type));
    }
}

 

메서드들이 허용하는 타입을 제한하고 싶을 때 한정적 타입 토큰을 활용하자.