Rah*_*pta 8 java stack-overflow
我已经从这个和这个 答案中理解了你的代码可能进入无限循环导致stackOverFlowError的可能情况,但我不明白如何在这里复制相同的场景,
public class A {
private B b = new B();
@Override
public String toString() {
return "b "+b;
}
}
public class B {
private A a = new A();
@Override
public String toString() {
return "";
}
}
public class StackoverflowErrorTest {
public static void main(String[] args) {
A a = new A();
System.out.println(a);
}
}
Run Code Online (Sandbox Code Playgroud)
此代码生成下面的堆栈跟踪: -
Exception in thread "main" java.lang.StackOverflowError
at stackoverflowerror.B.<init>(B.java:5)
at stackoverflowerror.A.<init>(A.java:5)
.
.
.
Run Code Online (Sandbox Code Playgroud)
根据我的理解,当我在main方法中打印对象'a'时,它将调用A类的toString方法,在该方法中,我将返回B类的对象,该对象将隐式调用B类的toString方法.现在,在B类的toString方法中,我返回的是一个空字符串.那么无限循环的范围如何以及在何处进入图片.请解释.
问题不在于toString,而在于private B b = new B();和private A a = new A();.
您正在创建一个创建B的A,它创建一个创建B的A,依此类推
而stacktrace说的完全相同:B.<init>意味着初始化器,而不是toString.它还指向抛出异常的行:B.java:5和A.java:5
实时代码:https://ideone.com/H8wwOR
如果你真的需要保持A在B和B中A,你可以使用任何参数的构造函数或通过setter方法传递它们:
class A {
private B b;
public A(B b) {
this.b = b;
}
}
class B {
private A a;
public A getA() {
return this.a;
}
public void setA(A a) {
this.a = a;
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用它们像:
B b = new B();
A a = new A(b);
b.setA(a);
Run Code Online (Sandbox Code Playgroud)
这是一个简化的示例,因此您可以了解.在大型应用程序中,您可能需要添加构建器,字段/构造函数参数注入或工厂(如果需要).
它进入了无休止的事件循环.toString()在这种情况下,该方法是无辜的:
main创建该类的实例AA该类B在初始化时创建该类的实例B该类A在初始化时创建该类的实例2局部变量在堆栈上分配,这StackOverflowError是一个错误的递归调用的结果.
在发生堆栈溢出时抛出,因为应用程序过于严重.
建议的解决方案,删除类A中类的引用,B因为它未使用:
public class B {
@Override
public String toString() {
return "";
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
821 次 |
| 最近记录: |