1. 递归方法

以下代码为核心代码,省略了不必要的业务流程,用来说明问题:

private boolean getRecommendListAndMatch(String newCycleEndDateStr, String tag) {boolean isMatchSuccess = false;// 获取数据BaseResult recommendList = dataMatchService.getRecommendListByPara();// 数据处理assert recommendList != null;if (recommendList.data.total > 0) {// 比较复杂的业务流程isMatchSuccess = true;} else {log.info("结束时间:{} 内无符合条件的数据!", newCycleEndDateStr);}// 递归调用方法if (isMatchSuccess) {getRecommendListAndMatch(newCycleEndDateStr, tag);}return isMatchSuccess;}

在网上找了几张图片:

这是一个很典型的递归调用


栈是一种比较简单的数据结构,具有后进先出的特性。



栈本身是一个线性表,但是在这个表中只有一端允许数据的进出。那为什么方法要放在栈结构内呢?比如方法A调用方法B,方法A的栈帧要先入栈(A的方法体和参数都要保存到B方法调用结束,否则B方法用的A里的参数就会出现空指针了)然后入栈B方法的数据,B方法调用结束,B方法的栈帧被弹出,此时如果A方法不再调用其他方法,A方法执行完了之后也会被弹出。


可想而知,如果递归方法的参数、对象较多再加上递归层数较多时,栈的空间毕竟是有限的,溢出就不足为奇了。

2. 重构代码

重构递归方法的逻辑不复杂,这里提供一种,使用 do while 实现递归逻辑:

 // 1. 调用条件boolean isMatchSuccess;do {// 2. 修改调用条件isMatchSuccess = getRecommendListAndMatch(newCycleEndDateStr, tag);// 3. 判断调用条件是否成立} while (isMatchSuccess);

三个点:

  • 判断是否再次调用的条件
  • do方法体里对调用条件的处理
  • while再次判断调用条件

主方法的调整(删掉递归调用):

private boolean getRecommendListAndMatch(String newCycleEndDateStr, String tag) {boolean isMatchSuccess = false;// 获取数据BaseResult recommendList = dataMatchService.getRecommendListByPara();// 数据处理assert recommendList != null;if (recommendList.data.total > 0) {// 比较复杂的业务流程isMatchSuccess = true;} else {log.info("结束时间:{} 内无符合条件的数据!", newCycleEndDateStr);}return isMatchSuccess;}

重构后,每次调用结束,方法帧都会从栈内弹出,从而避免了长时间过度占用栈空间的问题。

【Java报错】记录一次调用递归方法导致的 StackOverFlowError 及如何重构递归代码避免栈溢出相关推荐

  1. Errors报错记录

    Errors报错记录 前言 Error1 Error2 Error3 Error4 Error5 Error6 Error7 Error8 Error9 Error10 Error11 总结 前言 记 ...

  2. 【jenkins打包maven项目报错记录】

    jenkins打包maven项目报错记录 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3 ...

  3. Structured Streaming报错记录:Overloaded method foreachBatch with alternatives

    Structured Streaming报错记录:Overloaded method foreachBatch with alternatives [文章目录] Structured Streamin ...

  4. 【VINS-Mono】RealsenseD435i运行VINS-Mono,在ubuntu18.04和opencv3和cv_bridge的报错记录

    VINS-Mono(A Robust and Versatile Monocular Visual-Inertial State Estimator) https://github.com/HKUST ...

  5. win10安装MySQL数据库和MyServer数据库及其报错记录

    锚点: Win10装MySQL数据库及报错记录 Win10装MySever数据库及报错记录 <----------------分 隔 符----------------> Win10装My ...

  6. java报错MalformedURLException: unknown protocol: c

    java报错:MalformedURLException: unknown protocol: c 1. 报错情况: 部分代码: //打开图片path="C:/Users/MyUser/im ...

  7. oracle 被另一用户锁定,Oracle报错记录被另外一个用户锁定的解决方案

    原因 当一个用户对数据进行修改时,若没有进行提交或者回滚,Oracle不允许其他用户修改该条数据,在这种情况下修改,就会出现:"记录被另外一个用户锁定"错误. 解决 查询用户.数据 ...

  8. java报错-找不到或无法加载主类(Error: Could not find or load main class)

    此文首发于我的个人博客:java报错-找不到或无法加载主类(Error Could not find or load main class) - zhang0peter的个人博客 比如说test.ja ...

  9. php curl 不验证ssl,PHP Curl https跳过ssl证书认证报错记录及解决

    PHP Curl https跳过ssl证书认证报错记录及解决 function get($url = '', $cookie = '') { $ch = curl_init(); curl_setop ...

最新文章

  1. shell 获取ora报错信息_频发:故障排除之又见 ORA-4031丨云和恩墨技术通讯
  2. Android深度探索读书笔记 第七章
  3. 框架应用 : Spring MVC - 开发详述
  4. CentOS上安装Python3.7.4
  5. ecs使用脚本安装oracle
  6. uniapp 仿钉钉考勤统计页面的日历组件,通过日历展示每日考勤打卡情况,支持在日历上打两种不同类型的点,大致适配各种分辨率
  7. java中quickhit_关于java的QuickHit打字游戏小项目
  8. 【Flink】flink-1.12 通过 -t 指定模式后无法指定yarn参数
  9. ArcGIS10.8版本的下载安装及其注意事项
  10. vue下用canvas实现图片标注工具,允许图片放大、缩小,允许拖拽图片
  11. arm开发板挂载win10和ubuntu haneWIN NFS Server
  12. java application.doevents_Application.DoEvents()笔记
  13. 计算机考研各省份学校,想考研究生,哪个省份的高校更容易考上?
  14. C# Panel半透明
  15. 划重点 2022面试必刷461道大厂架构面试真题汇总+面经+简历模板
  16. Vue 组件之间传值
  17. 涨分神器-基于PPYOLOE的切图和拼图解决方案
  18. Follow My Heart Of Jan.Feb.Mar. 2023
  19. 手机屏幕显示正常但是触摸有一部分出问题,是内屏坏了吗?保修期内手机该不该走官方售后?
  20. 关系型数据库中的关键字、主关键字和候选关键字

热门文章

  1. 【转】windows Server2012安装iis
  2. HOWTO:如何在代码中获取安装包目标机上的Windows Installer(MSI)版本
  3. DataGrid 完全攻略之二(把数据导出到Excel)
  4. linux 脚本 if else,基于shell的if和else详解
  5. mysql获取用户名_mysql-LEFT JOIN 3列获取用户名
  6. java中this的含义_Javascript中的this的含义
  7. css3 渐变色 3种,css3实现渐变色文字的三种方法
  8. Android Studio同步失败设置代理,Android Studio如何设置代理?
  9. mt4虚拟服务器在哪里看,mt4查看自己服务器地址
  10. 脚本必须位于html的,js 前端第三剑客