You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何读取JSON同一字段中不同类型的数值?Java类型转换异常排查

解决JSON解析sentiment字段时的ClassCastException问题

这个问题我之前也碰到过,根源在于JSON本身没有区分整数和浮点数类型,而Java是强类型语言——当你解析JSON里的sentiment字段时,像0.000这种整数形式的浮点数,很多JSON解析库(比如Jackson、Gson或者原生JSONObject)会默认把它解析成Long类型,而带小数部分的-0.786会被解析成Double类型,后续你强转的时候自然就会抛出ClassCastException

下面给你几个实用的解决方案:

1. 实体类字段统一用Double类型

如果是用实体类映射JSON的话,直接把sentiment字段定义为Double(注意用包装类,避免null值问题),解析库会自动把Long类型的数值转换成Double:

public class NewsItem {
    private int id;
    private String company;
    private String title;
    private Double sentiment; // 用Double包装类
    
    // 生成getter、setter方法
}

这样不管JSON里是0.000还是-0.786,都会被正确解析成Double类型,不会出现类型转换异常。

2. 配置JSON解析器强制统一数值类型

如果你用的是Jackson,可以通过配置ObjectMapper来强制所有数值都解析成Double:

ObjectMapper objectMapper = new ObjectMapper();
// 强制将所有浮点数值解析为Double
objectMapper.enable(DeserializationFeature.USE_DOUBLE_FOR_FLOATS);
// 如果你需要处理更精确的数值,也可以用BigDecimal:
// objectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);

// 然后解析JSON数组或对象
List<NewsItem> newsList = objectMapper.readValue(jsonString, new TypeReference<List<NewsItem>>(){});

如果是Gson,可以自定义反序列化器:

Gson gson = new GsonBuilder()
    .registerTypeAdapter(Double.class, (JsonDeserializer<Double>) (json, typeOfT, context) -> {
        JsonElement element = json.getAsJsonPrimitive();
        if (element.isNumber()) {
            return element.getAsNumber().doubleValue();
        }
        throw new JsonParseException("Invalid numeric value for sentiment");
    })
    .create();

3. 手动解析时先判断类型再转换

如果是手动用JSONObject解析(比如org.json库),不要直接强转,先判断对象类型再做转换:

// 假设你遍历JSON数组中的每个对象
JSONArray jsonArray = new JSONArray(jsonString);
for (int i = 0; i < jsonArray.length(); i++) {
    JSONObject item = jsonArray.getJSONObject(i);
    Object sentimentObj = item.get("sentiment");
    Double sentiment;
    
    if (sentimentObj instanceof Long) {
        sentiment = ((Long) sentimentObj).doubleValue();
    } else if (sentimentObj instanceof Double) {
        sentiment = (Double) sentimentObj;
    } else {
        // 处理特殊情况,比如字符串形式的数值
        sentiment = Double.parseDouble(sentimentObj.toString());
    }
    
    // 后续使用sentiment变量
}

这样就能完美解决不同数值类型导致的转换异常问题了。

内容的提问来源于stack exchange,提问作者Joseph Ang

火山引擎 最新活动