item 33) 타입 안전 이종 컨테이너를 고려하라
타입 안전 이종 컨테이너
하나의 컨테이너에서 매개변수화 할 수 있는 타입의 수가 제한된다.
컨테이너 대신 키를 매개변수화 한 다음 컨테이너에 값을 넣거나 뺄 때 매개변수화 한 키를 같이 제공하는 설계 방식이다.
예제
public class Favorites {
private Map<Class<?>, Object> favorites = new HashMap<>();
public <T> void putFavorite(Class<T> type, T instance) {
favorites.put(Objects.requireNonNull(type), instance);//해당 객체가 Null이면, NullPointerException 발생
}
public <T> T getFavorite(Class<T> type) {
return type.cast(favorites.get(type));
}
//타입 안전 이종 컨테이너 패턴
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);
System.out.println(favoriteString);
System.out.println(favoriteInteger);
Class<?> favoriteClass = f.getFavorite(Class.class);
System.out.printf("%s %x %s%n", favoriteString, favoriteInteger, favoriteClass.getName());
}
}
getFavorite 메서드에서는 cast메서드를 사용해 Object 객체를 Class 객체가 가리키는 T 타입으로 동적 형변환한다.
제약 사항 1)
악의적인 클라이언트가 Class 객체를 로 타입으로 넘기면 타입 안전성이 깨진다. 하지만 컴파일 단에서 경고가 뜨긴 할 것이다.
타입 불변식을 어기는 일이 없도록 보장하려면, putFavorite 메서드에서 인수로 주어진 instance의 타입이 type으로 명시한 타입과 같은지 type.cast메서드를 사용해 확인하면 된다.
제약 사항 2)
Class 객체를 얻을 수 없는 실체화 불가 타입(List 등과 같은 Collections..)에는 사용 불가
한정적 타입 토큰 활용
단순히 한정적 타입 매개변수나 한정적 와일드카드를 사용해 표현가능한 타입을 제한하는 타입 토큰
메서드들이 허용하는 타입을 제한하고 싶을 때 사용한다.
asSubClass 메서드를 통해 클래스는 형변환을 안전하게 수행하도록 하고, 호출된 인스턴스 자신의 Class 객체를 인수가 명시한 클래스로 형변환한다.
Last updated