Java中解析带泛型的JSON必须用TypeToken,因泛型类型擦除导致直接传List.class会反序列化为List;TypeToken通过匿名子类固化泛型信息,使Gson能识别完整类型如List。
json 怎么使用">
Java中用Gson解析带泛型的JSON(比如 List<user></user>),不能直接传 List.class,否则反序列化出来的是 List<linkedtreemap></linkedtreemap>,运行时一取元素就抛 ClassCastException。根本原因在于Java泛型类型擦除——编译后 List<user></user> 和 List<string></string> 都只剩 List,Gson无法知道你要的是哪种。
为什么必须用 TypeToken>
TypeToken 是 Gson 提供的“类型占位器”,它通过匿名子类把泛型信息固化到字节码里,让 Gson 在运行时能读到完整类型,比如 List<user></user> 而不是模糊的 List。
- 错误写法(会出错):
gson.fromJson(json, List.class)→ 元素是LinkedTreeMap - 正确写法:
gson.fromJson(json, new TypeToken<list>>() {}.getType())</list>
基本用法:解析 List 类型
假设你有 JSON 字符串表示用户列表,对应实体类 User:
[{"id":1,"name":"张三"},{"id":2,"name":"李四"}]
解析代码如下:
Gson gson = new Gson();
String json = "[{\"id\":1,\"name\":\"张三\"},{\"id\":2,\"name\":\"李四\"}]";
Type type = new TypeToken<list>>() {}.getType();
List<user> users = gson.fromJson(json, type); // ✅ 正确拿到 List<user></user></user></list>
处理嵌套泛型(如 Response>)
常见统一响应结构:
{"code":200,"message":"ok","data":[{"id":1,"name":"王五"}]}
对应类:
public class ApiResponse<t> {
int code;
String message;
T data;
}</t>
解析时要一层层写出泛型:
Type type = new TypeToken<apiresponse>>>() {}.getType();
ApiResponse<list>> response = gson.fromJson(json, type);
List<user> list = response.data; // ✅ 类型安全
</user></list></apiresponse>
封装通用解析方法(注意泛型擦除陷阱)
不能直接写 <t> List<t> parseList(String json)</t></t> 并在内部用 TypeToken<list>>()</list> —— 因为方法签名里的 T 在运行时已擦除,匿名子类捕获不到具体类型。
正确做法是传入 Class<t></t>,再逐个解析元素:
public static <t> List<t> parseList(String json, Class<t> clazz) {
JsonArray array = JsonParser.parseString(json).getAsJsonArray();
List<t> list = new ArrayList();
for (JsonElement elem : array) {
list.add(new Gson().fromJson(elem, clazz));
}
return list;
}
// 调用:List<user> users = parseList(jsonStr, User.class);
</user></t></t></t></t>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











