Java 클래스가 제네릭(Generic) 타입일 때, 이를 Gson 라이브러리로 JSON 직렬화(Serialization) 및 역직렬화(Deserialization)하려면 특별한 처리가 필요합니다.
Gson은 com.google.gson.reflect.TypeToken 클래스를 제공하여 이 문제를 해결합니다. TypeToken 객체를 생성하면서 대상 클래스의 타입을 전달하면, Gson이 제네릭 클래스에 어떤 실제 타입이 사용되었는지 정확히 파악할 수 있습니다.
이는 Java의 타입 소거(Type Erasure) 특성 때문에 발생하는 문제를 우회하기 위한 방법으로, 익명 하위 클래스를 통해 런타임에도 제네릭 타입 정보를 유지하는 기법입니다.
문법(Syntax)
public class TypeToken<T> extends java.lang.Object
예제(Example)
아래 예제는 List<String> 타입의 리스트를 JSON 문자열로 직렬화한 후, 다시 원래의 리스트 객체로 역직렬화하는 과정을 보여줍니다.
import java.lang.reflect.Type;
import java.util.*;
import com.google.gson.*;
import com.google.gson.reflect.*;
public class GenericTypesJSONTest {
public static void main(String[] args) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
List<String> list = Arrays.asList("INDIA", "AUSTRALIA", "ENGLAND", "SOUTH AFRICA");
String jsonStr = gson.toJson(list);
System.out.println(jsonStr);
Type listType = new TypeToken<List<String>>() {}.getType();
list = gson.fromJson(jsonStr, listType);
System.out.println(list);
}
}실행 결과(Output)
[
"INDIA",
"AUSTRALIA",
"ENGLAND",
"SOUTH AFRICA"
]
[INDIA, AUSTRALIA, ENGLAND, SOUTH AFRICA]핵심 포인트 정리
- 직렬화: 일반적인 경우
gson.toJson()만으로 충분하며, 제네릭 타입 정보 없이도 문제없이 동작합니다. - 역직렬화:
gson.fromJson()호출 시 대상 타입이 제네릭이라면 반드시TypeToken을 사용해야 합니다. 그렇지 않으면 요소들이LinkedTreeMap등으로 잘못 변환될 수 있습니다. - 익명 클래스 활용:
new TypeToken<List<String>>() {}처럼 중괄호를 붙여 익명 하위 클래스로 생성해야 런타임에 제네릭 타입 정보가 보존됩니다.