You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

REST API获取JSON转Java对象时多次运行触发StackOverflowError求助

解决JSON转Java对象列表时的StackOverflowError问题

问题描述

我正在尝试将通过REST API接收的JSON文件转换为Java对象列表。初始运行时一切正常,但多次运行后会触发StackOverflowError。若不调用该转换方法,程序运行完全正常。目前我无法定位问题原因,恳请提供解决方案。报错信息如下:

Exception in thread "main" java.lang.StackOverflowError at org.json.JSONTokener.nextClean(JSONTokener.java:292) at org.json.JSONTokener.nextValue(JSONTokener.java:422) at org.json.JSONObject.(JSON...


可能的原因与解决方案

结合你遇到的「初始正常、多次调用后栈溢出」的特殊情况,我整理了几个最可能的排查方向和解决办法:

  • 检查Java对象的循环引用
    如果你是自己写解析逻辑或者用了简单的映射工具,先确认你的实体类之间有没有循环引用(比如User类里有Order对象,Order类又反过来持有User引用)。org.json在处理这种循环映射时,多次调用会让递归深度不断累积,最终触发栈溢出。
    解决办法:给循环引用的字段添加忽略注解(比如用Jackson的话是@JsonIgnore,自定义解析就手动跳过该字段),或者调整对象结构打破循环依赖。

  • 不要复用JSON解析实例
    很多开发者会图方便复用JSONTokener、JSONObject这类实例,但org.json的这些类内部维护了解析状态,多次复用会导致内部指针混乱,反复解析时递归调用的栈深度越来越深。
    解决办法:每次处理REST返回的JSON字符串时,都重新创建解析实例,比如:

    // 正确示例:每次转换都新建解析实例
    public List<MyEntity> parseJsonToList(String jsonResponse) {
        // 每次都新建JSONTokener,不要复用
        JSONTokener tokener = new JSONTokener(jsonResponse);
        JSONArray jsonArray = new JSONArray(tokener);
        List<MyEntity> resultList = new ArrayList<>();
        
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject obj = jsonArray.getJSONObject(i);
            // 映射到实体类的逻辑...
            resultList.add(mapToEntity(obj));
        }
        return resultList;
    }
    
  • 检查REST返回的JSON是否有异常结构
    初始运行正常但后续报错,有可能是某次请求返回的JSON出现了极深的嵌套结构(比如十几层甚至几十层的嵌套对象/数组)。org.json解析这种结构时,递归调用的栈会超过JVM的栈容量限制。
    解决办法:打印每次请求的JSON内容,排查是否存在异常的深嵌套。如果是,把递归解析改成迭代式解析,或者在JVM启动参数里适当调大栈容量(比如-Xss2m,但这只是临时方案,最好还是优化解析逻辑)。

  • 排查内存泄漏问题
    多次调用转换方法后,如果有大量解析后的对象被静态集合或者全局变量持有不释放,会导致内存占用过高,间接压缩栈空间引发栈溢出。
    解决办法:用VisualVM或者JProfiler这类工具分析内存使用情况,检查转换方法是否有内存泄漏,比如静态List一直添加对象却从不清理。

  • 考虑更换更成熟的JSON库
    org.json库比较基础,在高频调用或者复杂场景下的稳定性不如Jackson、Gson这些主流库。它们对循环引用、深嵌套的处理更智能,内存管理也更优。
    比如用Jackson实现转换的示例:

    // 初始化ObjectMapper(可以全局单例)
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    
    public List<MyEntity> convertWithJackson(String jsonResponse) throws IOException {
        return OBJECT_MAPPER.readValue(jsonResponse, new TypeReference<List<MyEntity>>() {});
    }
    

内容的提问来源于stack exchange,提问作者Marius Pop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:59:52