实战解析:JSONObject与JSONArray在Java项目中的核心操作与避坑指南 1. JSONObject与JSONArray基础概念解析在Java项目中处理JSON数据时JSONObject和JSONArray是最常用的两个工具类。简单来说JSONObject相当于一个键值对集合用大括号{}包裹例如用户信息{ id: 1001, name: 张三, vip: true }JSONArray则是有序的值集合用中括号[]包裹例如订单列表[ {orderId: 20230001, amount: 99.9}, {orderId: 20230002, amount: 199.0} ]实际开发中最容易混淆的是两者的嵌套关系。比如电商系统中一个用户可能有多个订单这时数据结构应该是{ user: { name: 张三, orders: [ {id: O001, items: [...]}, {id: O002, items: [...]} ] } }这里外层的user是JSONObject其中的orders是JSONArray而每个订单又是包含items数组的JSONObject。2. 常用JSON库API对比2.1 Fastjson vs org.json在Java生态中主流JSON库的API设计差异很大。以创建包含用户信息的JSON对象为例Fastjson写法JSONObject user new JSONObject(); user.put(name, 李四); user.put(age, 25); // 输出{name:李四,age:25}org.json写法JSONObject user new JSONObject(); user.put(name, 李四); user.putOpt(age, 25); // putOpt会忽略null值 // 输出{name:李四,age:25}关键区别空值处理Fastjson的put()会保留null而org.json的putOpt()会过滤类型安全org.json的getXXX()方法会抛出JSONException而Fastjson有更灵活的类型转换性能Fastjson在序列化/反序列化速度上通常更快2.2 实际项目选型建议新项目推荐使用Jackson或GsonAPI更现代且线程安全老系统维护根据现有库选择保持一致的风格Android开发优先考虑Gson体积更小3. 核心操作实战3.1 构建复杂JSON结构假设要构建一个包含商品列表的订单数据// 商品1 JSONObject item1 new JSONObject(); item1.put(sku, A001); item1.put(price, 59.9); // 商品2 JSONObject item2 new JSONObject(); item2.put(sku, B002); item2.put(price, 129.0); // 商品列表 JSONArray items new JSONArray(); items.add(item1); items.add(item2); // 完整订单 JSONObject order new JSONObject(); order.put(orderNo, 20230815001); order.put(items, items); order.put(total, 188.9);生成的JSON结构{ orderNo: 20230815001, items: [ {sku: A001, price: 59.9}, {sku: B002, price: 129.0} ], total: 188.9 }3.2 解析JSON数据从API响应中解析数据时要注意防御性编程String jsonStr {...}; // 假设是上面的订单JSON JSONObject order JSON.parseObject(jsonStr); // 安全获取值 String orderNo order.optString(orderNo, default); double total order.optDouble(total, 0.0); // 处理数组 JSONArray items order.getJSONArray(items); for (int i 0; i items.size(); i) { JSONObject item items.getJSONObject(i); String sku item.getString(sku); // 业务处理... }4. 高频踩坑点与解决方案4.1 空指针异常典型场景JSONObject data json.getJSONObject(nonExistKey); // 抛出异常正确做法// 方法1使用optXXX方法 JSONObject data json.optJSONObject(nonExistKey); // 方法2先检查key是否存在 if (json.has(nonExistKey)) { data json.getJSONObject(nonExistKey); }4.2 类型转换问题当JSON中的数字值被写成字符串时// 错误写法 int id json.getInt(id); // 如果id是字符串1001会报错 // 正确写法 int id json.optInt(id); // 自动类型转换4.3 日期格式化建议统一使用ISO8601格式JSONObject event new JSONObject(); event.put(createTime, new SimpleDateFormat(yyyy-MM-ddTHH:mm:ssZ) .format(new Date()));5. 性能优化技巧5.1 批量操作优化处理大型JSON数组时// 低效写法 for (int i 0; i bigArray.size(); i) { process(bigArray.getJSONObject(i)); } // 高效写法Fastjson特有 ListJSONObject list JSON.parseArray(bigArray.toJSONString(), JSONObject.class); list.parallelStream().forEach(this::process);5.2 缓存重用频繁创建的JSON对象可以使用ThreadLocal缓存private static final ThreadLocalJSONObject CACHE ThreadLocal.withInitial(JSONObject::new); void process() { JSONObject json CACHE.get(); json.clear(); // 重用前清空 // 填充数据... }6. Spring Boot项目中的最佳实践6.1 统一响应封装推荐使用ResponseEntity包装JSON响应GetMapping(/orders/{id}) public ResponseEntityJSONObject getOrder(PathVariable String id) { JSONObject result new JSONObject(); result.put(code, 200); result.put(data, orderService.getOrder(id)); return ResponseEntity.ok(result); }6.2 参数校验结合Validation APIPostMapping(/users) public void createUser(Valid RequestBody JSONObject user) { // 会自动校验JSON中的字段是否符合注解规则 }在DTO类上添加注解public class UserDTO { NotBlank private String name; Min(18) private Integer age; // getters/setters... }