代码演示一:抛出StackOverflowError
package com.codegen;
import lombok.ToString;
public class Test {
public static void main(String[] args) {
B b = new B();
A a = new A(b);
b.setA(a);
System.out.println(a); // 输出循环依赖中的的任一对象
}
@ToString
static class A {
private B b ;
public A(B b) {
this.b = b;
}
}
@ToString
static class B {
private A a;
public void setA(A a) {
this.a = a;
}
}
}
以上代码将抛出StackOverflowError
代码演示2:正常运行
package com.codegen;
import lombok.ToString;
public class Test {
public static void main(String[] args) {
B b = new B();
A a = new A(b);
b.setA(a);
System.out.println(1); // 修改这里,不打印任何对象
}
@ToString
static class A {
private B b ;
public A(B b) {
this.b = b;
}
}
@ToString
static class B {
private A a;
public void setA(A a) {
this.a = a;
}
}
}
以上代码正常运行,通过Debug可以看到AB两个对象的确相互依赖。
StackOverflowError出现的原因
再JVM内存模型中,互相依赖的对象可以做到很好的内存划分,仅仅只是A指向B,B指向A而已。不会出现OutOfMemeryError
,更不会直接抛出StackOverflowError
。代码演示一中出现StackOverflowError的原因是我们输出了a
对象,而AB两个类均覆盖了toString方法要求输出对象的所有引用,这就导致在运行期间出现死循环调用a和b的toString方法,当方法的调用达到栈深度时则出现了StackOverflowError。
(完)