이펙티브자바 33

참치돌고래·2022년 12월 27일
0

이펙티브 자바

목록 보기
18/21

이종 컨테이너 패턴

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

type token : 컴파일타임 타입 정보와 런타임 타입 정보를 알아내기 위해 메서드들이 주고 받는 class 리터럴


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);
        }
        public <T> T getFavorite(Class<T> type){
            return type.cast(favorites.get(type));
        }
    }

getFavorite 는 처음에 Map 에서 Class를 꺼내면 Object 이기때문에 T 로 캐스팅하여 반환한다.
하지만 악의적인 클라이언트 코드를 통해 getFavorite 시 오류가 발생할 수 있다.

putFavorites(Class(Integer.class)), "Integer의 인스턴스가 아닙니다.");
int favoriteInteger = f.getFavorite(Integer.class);

ClassCastExcpetion 발생

이를 해결하기 위해 putFavorite 에 cast 메소드를 사용

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

해당 코드로 변경시, getFavorite 메소드에서 오류가 발생하는 것이 아니라,
putFavorite 메소드에서 오류 발생

슈퍼 타입 토큰

위의 Favotie 은 List 형태의 인스턴스를 저장을 할 수 가 없다.
List<String>.class 라는 Class 객체를 얻을 수 없기 때문이다.
하지만 슈퍼 타입 토큰을 통해 해당 부분을 우회하여 저장할 수 있다.

spring - ParameterizedTypeReference

Favorites f = new Favorites();
List<String> pets = Arrays.asList("개", "고양이", "앵무");
f.putFavotie(new TypeRef<List<String>>(){}. pets);
List<String> listOfStrings = f.getFavorite(new TypeRef<List<String>>(){});

spring에서의 ParameterizedTypeReference

List<String> list = new ArrayList<>();
list.add("apple");
list.add("banana");

ParameterizedTypeReference<List<String>> typeRef = 
	ParameterizedTypeReference<List<String>>() {};
ResponseEntity<List<String>> response = restTemplate.exchange("/fruit", HttpMethod.GET, null, typeRef);
List<String> fruits = response.getBody();
profile
안녕하세요

0개의 댓글