아이템 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));
}
}
형 안전 다형성 컨테이너의 문제점
- Class(raw type)를 인자로 넘기면 형이 지정되지 않았기 때문에 형 안정성이 깨질수 있음
favorites.put(type, type.cast(instance));
등과 같이 Class cast메서드로 커버 가능
- 실체화 불가능한 자료형은 쓸수 없음, 예를 들어
List<String>.class
는 제너릭 인터페이스 이기 때문에 class가 존재하지 않음- 언어 차원에서 지원되지 않기 때문에 실질적인 해결법이 없음
- 외부 라이브러리 사용 필요
asSubClass
- 실행 시점에 특정한 Class객체를 인자로 주어진 하위 클래스의 Class객체로 형 변환 해줌
- 성공하면 생성된 SubClass반환
- 실패하면
ClassCastException
발생
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>
와 같이 직접 구현할 수도 있다.