Java Map <string,object>强制转换为Map <string,string>在运行时不会抛出错误

时间:2019-01-23 07:20:34

标签: java collections classcastexception

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行?

2 个答案:

答案 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,这样会引发错误。