JSONObject 使用文档(Java/Android原生)
本文针对 Java/Android 原生org.json.JSONObject类详细说明其常用方法、核心区别及避坑要点适用于日常JSON解析场景帮助开发者规避常见异常提升解析安全性和效率。适用场景后端接口返回JSON数据解析、本地JSON数据构造与解析不适用于第三方JSON解析框架如Gson、FastJson。1. 介绍JSONObject 是原生JSON解析的核心类用于封装JSON对象键值对集合提供了一系列方法用于获取、设置、判断JSON中的键值对核心分为「严格模式方法」和「容错模式方法」对应 getXXX 系列和 optXXX 系列。引入依赖dependencygroupIdorg.json/groupIdartifactIdjson/artifactIdversion20200518/version/dependency2. 常用方法详解2.1 构造方法用于创建JSONObject实例常用2种方式// 1. 空构造后续手动添加键值对JSONObjectjsonnewJSONObject();// 2. 传入JSON字符串构造最常用注意字符串格式必须合法StringjsonStr{\msgid\:\123456\,\name\:\测试\};JSONObjectjsonnewJSONObject(jsonStr);// 格式错误会抛JSONException2.2 核心方法getXXX 系列严格模式核心特点键key不存在、键对应值为null或值类型不匹配时直接抛出 JSONException适用于「必填字段」的解析强制校验数据完整性。方法功能使用示例异常场景getString(String key)获取指定key的字符串值json.getString(“msgid”);key不存在、值为null、值不是字符串getInt(String key)获取指定key的int值json.getInt(“age”);key不存在、值为null、值不是数字含字符串数字getLong(String key)获取指定key的long值json.getLong(“id”);同getInt额外注意值超过int范围getBoolean(String key)获取指定key的boolean值json.getBoolean(“flag”);key不存在、值为null、值不是boolean含字符串true/“false”getJSONObject(String key)获取指定key的JSONObject子对象json.getJSONObject(“user”);key不存在、值为null、值不是JSONObjectgetJSONArray(String key)获取指定key的JSONArray数组json.getJSONArray(“list”);key不存在、值为null、值不是JSONArray2.3 核心方法optXXX 系列容错模式核心特点键不存在、值为null时不抛异常返回对应类型的默认值值类型不匹配时返回默认值部分场景除外适用于「非必填字段」的解析提升程序稳定性。所有optXXX方法均有重载版本可自定义默认值推荐使用比无参版更安全。方法无参默认值重载方法自定义默认值使用示例注意点optString(String key)“”空字符串optString(String key, String defaultValue)optString(“name”, “未知”)值为null时返回默认值无异常optInt(String key)0optInt(String key, int defaultValue)optInt(“age”, -1)值为字符串数字如123时返回0坑点optLong(String key)0LoptLong(String key, long defaultValue)optLong(“id”, 0L)避免用于超长数字解析如雪花ID建议先转字符串optBoolean(String key)falseoptBoolean(String key, boolean defaultValue)optBoolean(“flag”, false)值为字符串true/false时返回false大坑optJSONObject(String key)nulloptJSONObject(String key, JSONObject defaultValue)optJSONObject(“user”, new JSONObject())返回null时需手动判空避免空指针optJSONArray(String key)nulloptJSONArray(String key, JSONArray defaultValue)optJSONArray(“list”, new JSONArray())返回null时需手动判空避免空指针2.4 辅助判断方法高频使用用于判断键的存在性和值的有效性避免盲目调用getXXX/optXXX方法减少异常。方法功能说明示例JSON{“a”:null,“b”:123}返回结果has(String key)判断key是否存在无论值是否为nulljson.has(“a”)、json.has(“c”)true、falseisNull(String key)判断key不存在或key存在但值为nulljson.isNull(“a”)、json.isNull(“c”)true、truelength()获取JSON对象中键值对的数量json.length()2keys()获取所有key的迭代器json.keys();迭代器包含a、“b”2.5 其他常用方法// 1. 向JSON对象添加键值对json.put(key,value);// 支持String、int、boolean等多种类型// 2. 删除指定keyjson.remove(key);// 3. 将JSON对象转为字符串格式化/非格式化StringjsonStrjson.toString();// 非格式化StringprettyJsonjson.toString(4);// 格式化缩进4个空格// 4. 获取所有值的集合JSONArrayvaluesjson.toJSONArray(json.keys());3. 常见坑点及避坑指南重点3.1 数字解析坑高频踩雷后端返回字符串数字如{“age”:“18”}时getInt/optInt会抛异常或返回0无法正确解析。✅ 正确做法先通过optString获取字符串再手动转为对应数字类型避免类型不匹配。// 错误示例intagejson.optInt(age);// 后端返回18返回0// 正确示例StringageStrjson.optString(age,0);intageInteger.parseInt(ageStr);3.2 布尔值解析坑后端返回字符串true/“false”如{“flag”:“true”}时optBoolean返回falsegetBoolean抛异常。✅ 正确做法通过optString获取字符串再与true比较判断。// 错误示例booleanflagjson.optBoolean(flag);// 返回false// 正确示例booleanflagtrue.equals(json.optString(flag,false));3.3 精度丢失坑金额、价格等字段用getDouble/optDouble解析会导致精度丢失如0.01变成0.0099999999。✅ 正确做法用optString获取字符串再转为BigDecimal类型。// 错误示例doublepricejson.optDouble(price);// 精度丢失// 正确示例StringpriceStrjson.optString(price,0.00);BigDecimalpricenewBigDecimal(priceStr);3.4 对象/数组判空坑optJSONObject/optJSONArray返回null而非空对象/空数组直接调用方法如length()会抛空指针。✅ 正确做法获取后先判空再进行后续操作。// 正确示例数组JSONArraylistjson.optJSONArray(list);if(list!nulllist.length()0){// 遍历数组}// 正确示例对象JSONObjectuserjson.optJSONObject(user);if(user!null!user.isEmpty()){// 获取对象中的字段}3.5 超大数字解析坑雪花ID、订单号等超长数字超过int范围用getInt解析会抛异常用optInt返回0。✅ 正确做法用optString获取或用getLong/optLong解析确保不超过long范围。4. 完整示例代码以下示例涵盖日常解析常见场景遵循上述规范可直接参考使用importorg.json.JSONArray;importorg.json.JSONException;importorg.json.JSONObject;importjava.math.BigDecimal;publicclassJsonParseDemo{publicstaticvoidmain(String[]args){// 模拟后端返回的JSON字符串StringjsonStr{\msgid\:\123456\,// 必填字符串\name\:\张三\,// 非必填字符串\age\:\25\,// 非必填数字字符串格式\flag\:\true\,// 布尔值字符串格式\price\:\99.99\,// 金额\user\:{\id\:1001,\phone\:\13800138000\},// 子对象\list\:[{\id\:1,\title\:\测试1\},{\id\:2,\title\:\测试2\}]// 数组};try{JSONObjectjsonnewJSONObject(jsonStr);// 1. 必填字段getStringStringmsgidjson.getString(msgid);// 2. 非必填字符串optString 默认值Stringnamejson.optString(name,未知用户);// 3. 非必填数字先转字符串再转intStringageStrjson.optString(age,0);intageInteger.parseInt(ageStr);// 4. 布尔值字符串判断booleanflagtrue.equals(json.optString(flag,false));// 5. 金额转BigDecimalStringpriceStrjson.optString(price,0.00);BigDecimalpricenewBigDecimal(priceStr);// 6. 子对象optJSONObject 判空JSONObjectuserjson.optJSONObject(user);Stringphone;if(user!null){phoneuser.optString(phone,未知号码);}// 7. 数组optJSONArray 判空 遍历JSONArraylistjson.optJSONArray(list);if(list!nulllist.length()0){for(inti0;ilist.length();i){JSONObjectitemlist.getJSONObject(i);intitemIditem.getInt(id);Stringtitleitem.optString(title,);System.out.println(数组项iditemId, titletitle);}}// 输出解析结果System.out.println(msgidmsgid);System.out.println(namename);System.out.println(ageage);System.out.println(flagflag);System.out.println(priceprice);System.out.println(phonephone);}catch(JSONExceptione){// 捕获解析异常如必填字段缺失、JSON格式错误e.printStackTrace();System.out.println(JSON解析失败e.getMessage());}catch(NumberFormatExceptione){// 捕获数字转换异常e.printStackTrace();System.out.println(数字转换失败e.getMessage());}}}