private static String tmp = "{\"data\":{\"vin\":\"LNBSCCAK9JD065606\",\"extParameter\":{\"systemTime\":\"2019-01-23 12:58:35\",\"fuelAmount\":20.0},\"pushType\":\"fuelWarn\"},\"type\":\"uaes-iot-public-service\"}";
public static void main(String[] args) {
JSONObject jsonObject = JSON.parseObject(tmp);
JSONObject data = JSON.parseObject(jsonObject.getString("data"));
// line 1
Map<String, String> result = (Map<String, String>) data.getInnerMap().get("extParameter");
for (Map.Entry<String, String> item: result.entrySet()) {
String key = item.getKey();
// line 2
String value = item.getValue();
}
}
上面的代码抛出
第2行的ClassCastExecption:无法将java.math.BigDecimal强制转换为 java.lang.String
但是结果类型是Map[String, String]
的缩写,如果地图的“值类型”不是字符串,为什么ClassCastExecption
会抛出第1行?
答案 0 :(得分:2)
结果类型仅为Map<String, String>
,因为您使用了不安全的类型转换。将会有一个关于此的编译器警告。
泛型类型仅在编译时存在,在运行时Map不会检查其组件类型。
String value = item.getValue();
由于泛型类型,编译器认为此Map仅包含String
,因此您可以编写上面的行。但是它实际编译成的是
String value = (String) item.getValue(); // cast inserted by compiler
,如果该值恰好是其他值,则此操作将失败。
"fuelAmount":20.0
这不是JSON中的字符串。 您必须自己将其转换为String(或处理从Map返回的其他类型的值)。
最好的解决方案可能是为JSON解析器创建一些“ bean”类以反序列化为该类。这些可以具有命名和键入的属性。
答案 1 :(得分:0)
字段"fuelAmount"
存储的是十进制值,因此系统尝试将您的十进制转换为要转换的String
,这样会引发错误。