실무에서 restTemplate을 이용하여 api 응답을 검증 하는 목적의 테스트 코드를 작성하면서 응답 값에 대한 검증을 하기 위해 응답을 ParameterizedTypeReference<> 타입으로 정의해서 작성해보았다!
private static final ParameterizedTypeReference<Map<String, Object>> RESPONSE_TYPE_PARAMETER =
new ParameterizedTypeReference<Map<String, Object>>() {}; // 제네릭 타입 정보 유지
ResponseEntity<Map<String, Object>> response =
restTemplate.exchange(
"https://bizapi.inicis.com/api/message",
HttpMethod.POST,
new HttpEntity<>(requestBody, headers),
RESPONSE_TYPE_PARAMETER // 타입 소거 문제 해결
);
ResponseEntity<Map<String, Object>> response =
restTemplate.exchange(
"https://bizapi.inicis.com/api/message",
HttpMethod.POST,
new HttpEntity<>(requestBody, headers),
Map.class // 타입 소거 문제 발생
);
제네릭 타입 소거란?
-> 자바는 컴파일 단계에서는 제네릭 정보를 유지하지만, 런타임에서는 타입 정보를 제거한다.
결국, Map<String, Object> 와 같은 제네릭 타입이 런타임 시에는 Map으로만 인식 된다.
예시코드
List<String> stringList = new ArrayList<>();
List<Integer> intList = new ArrayList<>();
System.out.println(stringList.getClass() == intList.getClass()); // true
1️⃣ RESPONSE_TYPE_PARAMETER는 제네릭 타입 정보를 유지하기 위해 필요함.
2️⃣ restTemplate.exchange()는 제네릭 타입 정보를 유지해야 올바른 응답 변환이 가능함.
3️⃣ RESPONSE_TYPE_PARAMETER를 사용하지 않으면 타입 소거 문제로 인해 변환 오류 발생 가능성이 있음.
4️⃣ 제네릭 타입 소거(Type Erasure)로 인해 Map<String, Object>가 보장되지 않음. 이를 해결하려면 ParameterizedTypeReference 사용이 필수적임.