本文详解在使用 Gson 解析含嵌套结构的 JSON 数组时,如何准确识别并安全处理 null 字段(包括 JSON null 和 Java null),避免 ClassCastException 或 NullPointerException。
本文详解在使用 gson 解析含嵌套结构的 json 数组时,如何准确识别并安全处理 `null` 字段(包括 json `null` 和 java `null`),避免 classcastexception 或 nullpointerexception。
在 Java 中使用 Gson 解析 JSON 时,一个常见误区是将 JSON 的 null 值等同于 Java 的 null 引用。实际上,Gson 将 JSON 中显式的 null(如 "cityName": null)解析为 JsonNull 实例,而非 Java 的 null——它是一个合法的 JsonElement 子类对象。因此,仅用 dataValue == null 判断无法捕获 JSON null,会导致后续强制类型转换(如 (JsonObject)dataValue)抛出 ClassCastException。
正确的做法是:统一使用 JsonElement 类型接收字段值,并通过 isJsonNull() 方法判断是否为 JSON null。同时,应避免不必要的字符串序列化与重新解析(如 dataObj.toString() + parser.parse(...)),这既低效又易出错。
以下是优化后的完整实现:
import com.google.gson.*;public class DataParser { public static JsonArray parseData(JsonArray data) throws JsonParseException { JsonArray dataArray = new JsonArray(); for (JsonElement dataObj : data) { // ✅ 直接使用 JsonElement,避免 toString() + parse() JsonObject obj = dataObj.getAsJsonObject(); JsonObject finalDataObj = new JsonObject(); JsonObject fieldsObj = obj.getAsJsonObject("fields"); // ✅ 安全获取嵌套对象 finalDataObj.add("key", obj.get("key")); finalDataObj.addProperty("cityName", displayName(fieldsObj.get("cityName"))); finalDataObj.addProperty("category", displayName(fieldsObj.get("category"))); dataArray.add(finalDataObj); } return dataArray; } public static String displayName(JsonElement dataValue) { // ✅ 同时检查:Java null(如字段缺失)和 JSON null(如 "cityName": null) if (dataValue == null || dataValue.isJsonNull()) { return ""; } try { // ✅ 确保是 JsonObject 后再取 name 字段 JsonObject obj = dataValue.getAsJsonObject(); JsonElement nameElement = obj.get("name"); return nameElement != null && !nameElement.isJsonNull() ? nameElement.getAsString() : ""; } catch (Exception e) { return ""; // 防御性处理:非 JsonObject 类型(如字符串、数字)也返回空串 } }}
关键改进点总结:
该方案确保输入中任意嵌套层级的 null 字段(如 {"cityName": null} 或缺失字段)均被安全映射为空字符串,输出符合预期格式,且具备生产级稳定性。