Effective Java 33. 타입 안전 이종 컨테이너를 고려하라

Jung Ho Seo·2020년 8월 18일
0

EffectiveJava

목록 보기
12/35
post-custom-banner

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

Heterogeneous container pattern

이종 컨테이너 패턴 이란, Set, 혹은 Map에 기본적인 사용방식 보다 유연한 사용방식이 필요할 때 사용한다. 컨테이너 대신 키를 매개변수화한 다음, 컨테이너에 값을 넣거나 뺄 때 매개변수화 한 키를 함께 제공하는 방식이다.

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

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

각 타입의 Class 객체를 매개변수화한 키 역할로 사용한다. 이 방식이 동작하는 이유는 class 클래스가 제네릭이기 때문이다. class의 리터럴 타입은 Class가 아닌 Class이다. 예컨대 String.class의 타입은 Class이고 Integer.class의 타입은 Class이다.

다음은 앞의 Favorites 클래스를 사용하는 예시다.

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

	f.putFavorite(String.class, "Java");
	f.putFavorite(Integer.class, 10);
	f.putFavorite(Class.class, Favorites.class);

	String s = f.getFavorite(String.class);
	int i = f.getFavorite(Integer.class);
	Class<?> c = f.getFavorite(Class.class);

}

이 클래스는 타입 안전하다. String을 integer를 반환하는 일은 절대로 없을 것이다.

구현은 다음과 같다

타입 안전 이종컨테이너 패턴 - 구현

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

	public <T> void putFavorite(Class<T> type, T instance){
		favorites.put(type, instance);
	}

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

이 코드에서 헷갈릴 수 있는 부분은, Map<Class<?>, Object> 부분이다. 비한정적 와일드카드 타입이라 이 맵 안에 아무것도 넣을 수 없다고 생각할 수 있지만, 사실은 그 반대, 와일드 카드 타입이 중첩(nested) 되있다.따라서 맵이아니라 키가 와일드 카드 타입인 것이다. 이는 모든 키가 서로 다른 매개변수화 타입일 수 있다는 뜻으로, Class, Class 등 다양한 방식으로 사용할 수 있다는 의미가 된다.

컬렉션 api로 대표되는 일반적인 제네릭 형태에서는 한 컨테이너가 다룰 수 있는 타입의 매개변수의 수가 고정되어 있다. 하지만 컨테이너 자체가 아닌 키를 타입 매개변수로 바꾸면 이런 제약이 없는 타입 안전한 이종 컨테이너를 만들 수 있다.

profile
책, 글, 개발
post-custom-banner

0개의 댓글