【已解决】Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to
GSON TypeToken 动态泛型
一、错误描述
Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.xxx
二、代码
自定义class RecReasonConf
@Data
@Builder
public static class RecReasonConf {
/**
* 推荐理由编号
*/
private String reasonCode;
/**
* 推荐理由类型
*/
private String reasontype;
}
泛型反序列化
public static <T> Map<String, T> gsonToMaps(String gsonString) {
Map<String, T> map = null;
if (gson != null) {
map = gson.fromJson(gsonString, new TypeToken<Map<String, T>>() {
}.getType());
}
return map;
}
运行编译
public static void main(String[] args) {
String str = "{\"A1\":{\"reasonCode\":\"A1\",\"reasontype\":\"FAVOR\"},\"A2\":{\"reasonCode\":\"A2\",\"reasontype\":\"FAVOR\"},\"A3\":{\"reasonCode\":\"A3\",\"reasontype\":\"FAVOR\"},\"B1\":{\"reasonCode\":\"B1\",\"reasontype\":\"CLICK\"},\"B2\":{\"reasonCode\":\"B2\",\"reasontype\":\"CLICK\"},\"B3\":{\"reasonCode\":\"B3\",\"reasontype\":\"CLICK\"},\"C\":{\"codePrefix\":\"C\",\"reasontype\":\"CLICK\"},\"D1\":{\"reasonCode\":\"D1\",\"reasontype\":\"EXPOSE\"},\"D2\":{\"reasonCode\":\"D2\",\"reasontype\":\"EXPOSE\"},\"D3\":{\"reasonCode\":\"D3\",\"reasontype\":\"EXPOSE\"},\"E\":{\"codePrefix\":\"E\",\"reasontype\":\"NEWEST\"}}";
Map<String,RecReasonConf> map = GsonUtil.gsonToMaps(str);
map.values().stream().findFirst().ifPresent(obj-> System.out.println(obj.getClass().getSimpleName()));
}
debug查看反序列结果

三、原因
带泛型的map被转成gson后,对象被擦除,变为LinkedTreeMap。所以无法被还原
四、改进方案
public static <T> Map<String, T> gsonToMaps(String gsonString,Class<T> clazz) {
Map<String, T> map = null;
if (gson != null) {
Type type = TypeToken.getParameterized(Map.class,String.class,clazz).getType();
map = gson.fromJson(gsonString, type);
}
return map;
}

浙公网安备 33010602011771号