通用函数中Gson解析泛型BaseResponse报错的解决方法咨询
问题解决方法及TypeToken泛型解析说明
TypeToken能否解析带泛型的对象
能。TypeToken是Gson专门用来规避Java泛型类型擦除问题的工具,单独使用匿名内部类方式(比如new TypeToken<BaseResponse<LogonResponse>>(){})时,能完整保留泛型的具体类型信息,因此可以正确解析带泛型的对象。
泛型decode函数报错原因
Java泛型存在类型擦除机制:编译后泛型参数T会被替换为Object。如果在泛型方法中直接使用new TypeToken<BaseResponse<T>>(){},Gson实际拿到的类型是BaseResponse<Object>,解析data字段时会默认转换成LinkedTreeMap,后续强转为具体业务类型(如LogonResponse)就会抛出ClassCastException。
解决方法
核心思路是让泛型方法能获取到具体的泛型类型信息,以下是两种常用方案:
1. 调用方传入TypeToken
将TypeToken作为参数传递给decode函数,直接利用它保留的泛型信息解析:
public <T> BaseResponse<T> decode(String json, TypeToken<BaseResponse<T>> typeToken) { Gson gson = new Gson(); return gson.fromJson(json, typeToken.getType()); } // 调用示例 BaseResponse<LogonResponse> response = decode(jsonStr, new TypeToken<BaseResponse<LogonResponse>>(){});
2. 动态构造ParameterizedType
通过反射动态构造包含具体泛型参数的ParameterizedType,无需调用方传入TypeToken,只需传入业务类型的Class对象:
public <T> BaseResponse<T> decode(String json, Class<T> dataClass) { Gson gson = new Gson(); Type targetType = new ParameterizedType() { @Override public Type[] getActualTypeArguments() { return new Type[]{dataClass}; } @Override public Type getRawType() { return BaseResponse.class; } @Override public Type getOwnerType() { return null; } }; return gson.fromJson(json, targetType); } // 调用示例 BaseResponse<GameMenuResponse> response = decode(jsonStr, GameMenuResponse.class);
可选优化:提前定义TypeToken子类
如果某些泛型类型频繁使用,可以提前定义对应的TypeToken子类,避免重复编写匿名内部类:
public class LogonResponseTypeToken extends TypeToken<BaseResponse<LogonResponse>>{} // 调用示例 BaseResponse<LogonResponse> response = decode(jsonStr, new LogonResponseTypeToken().getType());
内容的提问来源于stack exchange,提问作者GHH
相关产品推荐
相关产品推荐

