访问Map条目时遭遇ClassCastException问题求助
问题原因与解决方法
核心原因
你的JSON里"b"对应的值是嵌套JSON对象{"bb": "b1"},Jackson在解析JSON时,默认会把JSON对象转换成LinkedHashMap(实现了Map接口),而不是字符串。你声明的Map<String, String>是泛型限制为字符串值的Map,但实际b的value是Map类型,运行时强转就会抛出ClassCastException。
具体分析
- 调用
mapper.readValue(json, Map.class)时,未指定泛型类型,Jackson会将顶层JSON对象解析成LinkedHashMap<String, Object>:"a"对应的值是字符串"a1",类型为String"b"对应的值是嵌套JSON对象,被解析成LinkedHashMap<String, String>(内部"bb"对应"b1")
- 你将这个Map赋值给
Map<String, String> myMap属于未经检查的类型转换,编译器仅会给出警告但不报错;运行时调用myMap.get("b"),JVM尝试把实际的LinkedHashMap转成String,直接触发类型转换异常。
解决方案
方案1:将嵌套对象转为JSON字符串输出
如果需要把b的内容当作字符串输出,可通过Jackson将嵌套Map重新序列化为JSON字符串:
@Test public void test1() throws Exception { String json = "{" + "\"a\": \"a1\"," + "\"b\": {" + "\"bb\": \"b1\"" + "}" + "}"; final ObjectMapper mapper = new ObjectMapper(); Map<String, Object> myMap = mapper.readValue(json, Map.class); String contentA = (String) myMap.get("a"); System.out.println(contentA); // 把嵌套Map转成JSON字符串 Object bValue = myMap.get("b"); String contentB = mapper.writeValueAsString(bValue); System.out.println(contentB); // 输出 {"bb":"b1"} }
方案2:使用正确的泛型Map
如果需要保留嵌套结构,直接声明匹配的泛型类型:
@Test public void test1() throws Exception { String json = "{" + "\"a\": \"a1\"," + "\"b\": {" + "\"bb\": \"b1\"" + "}" + "}"; final ObjectMapper mapper = new ObjectMapper(); // 顶层Map的值可以是String或另一个Map Map<String, Object> myMap = mapper.readValue(json, Map.class); String contentA = (String) myMap.get("a"); System.out.println(contentA); // 将b的值转为对应的Map Map<String, String> bMap = (Map<String, String>) myMap.get("b"); System.out.println(bMap.get("bb")); // 输出 b1 }
也可以用更精确的泛型声明避免编译器警告:
Map<String, Object> myMap = mapper.readValue(json, new TypeReference<Map<String, Object>>() {});
方案3:使用实体类映射(推荐)
对于结构固定的JSON,创建对应实体类是最规范的做法,彻底避免类型转换问题:
// 顶层实体类 class Demo { private String a; private B b; // 生成getter、setter、toString方法 public String getA() { return a; } public void setA(String a) { this.a = a; } public B getB() { return b; } public void setB(B b) { this.b = b; } @Override public String toString() { return "Demo{a='" + a + "', b=" + b + "}"; } } // 嵌套的B类 class B { private String bb; public String getBb() { return bb; } public void setBb(String bb) { this.bb = bb; } @Override public String toString() { return "B{bb='" + bb + "'}"; } } @Test public void test1() throws Exception { String json = "{" + "\"a\": \"a1\"," + "\"b\": {" + "\"bb\": \"b1\"" + "}" + "}"; final ObjectMapper mapper = new ObjectMapper(); Demo demo = mapper.readValue(json, Demo.class); System.out.println(demo.getA()); // 输出 a1 System.out.println(demo.getB().getBb()); // 输出 b1 }
内容的提问来源于stack exchange,提问作者Michael S
相关产品推荐
相关产品推荐

