有趣的BUG之Stack Overflow
今天遇到一个很有意思的bug,当程序开发完成后打包到服务器运行,总是会出现栈溢出异常,经过排查发现,问题出现在一个接口上,但这个接口逻辑并不复杂,除了几局逻辑代码外和打印语句之外也没有其他的了,但是只要调用这个接口就马上会出现栈溢出的异常,随后对代码进行了排查,最后发现问题居然出现在日志打印语句上。
平常在开发过程中我们经过会通知打印日志来了解程序的运行状态,没想到今天在这上面翻了车,这个打印语句是打印一个对象,我们知道,当要打印一个对象的时候会自动调用对象的toString()
方法,项目中我们会使用lombok
插件来帮助我们生成对应的get、set、equals、hashcode、toString等方法,而打印的这个对象在由Spring容器管理的一个bean,我们给这个bean取名A,在A里面又依赖注入了另一个bean,我们取名B,A和B形成了循环依赖,且都重写了toString方法,所以当调用A的toString方法时,会调用B的toString方法,当调用B的toString又会调用A的toString,由此形成了死循环,最终导致了栈溢出的异常。
下面是我精简出的出现问题的代码结构,帮助大家避坑
类A结构
public class A {
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
@Override
public String toString() {
return "A{" +
"b=" + b +
'}';
}
}
类B结构
public class B {
private A a;
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
@Override
public String toString() {
return "B{" +
"a=" + a +
'}';
}
}
Spring配置文件,类A类B交给容器管理
<bean id="a" class="com.zlm.bean.A">
<property name="b" ref="b"/>
</bean>
<bean id="b" class="com.zlm.bean.B">
<property name="a" ref="a"/>
</bean>
主程序
public class App {
public static void main(String[] args) {
ClassPathXmlApplicationContext xmlApplicationContext = new ClassPathXmlApplicationContext("bean.xml");
A bean = xmlApplicationContext.getBean(A.class);
// 会报错
System.out.println(bean);
}
}
错误信息
Exception in thread "main" java.lang.StackOverflowError
分类:
BUG
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?