Java 为什么这个toString()方法会导致StackOverflowerError?
我已经从和了解了 回答,可能的情况是,您的代码可能会进入无限循环,导致StackOverflowerError,但我不明白相同的情况是如何在这里复制的Java 为什么这个toString()方法会导致StackOverflowerError?,java,stack-overflow,Java,Stack Overflow,我已经从和了解了 回答,可能的情况是,您的代码可能会进入无限循环,导致StackOverflowerError,但我不明白相同的情况是如何在这里复制的 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
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);
}
}
此代码正在生成以下堆栈跟踪:-
Exception in thread "main" java.lang.StackOverflowError
at stackoverflowerror.B.<init>(B.java:5)
at stackoverflowerror.A.<init>(A.java:5)
.
.
.
线程“main”java.lang.StackOverflower中出现异常
在StackOverflowerr.B.(B.java:5)
在StackOverflowerr.A.(A.java:5)
.
.
.
根据我的理解,当我在main方法中打印对象“a”时,它将调用一个类的toString方法,在该方法中,我将返回B类的对象,该对象将隐式调用B类的toString方法。现在,在B类的toString方法中,我返回的只是一个空字符串。那么无限循环的范围是如何以及在哪里出现的呢。请解释。当您在主菜单中调用
A A=newa()代码>,代码将调用A的构造函数,该构造函数将调用private B=new B()
,它将调用私有A=newa()无限循环的代码>等:)
这个问题根本与toString()
无关它进入了无休止的事件循环。在这种情况下,方法toString()
是无辜的:
方法main
创建类A
类A
在初始化时创建类B
的实例
类B
在初始化时创建类A
的实例
转到步骤2
局部变量在堆栈上分配,并且是错误递归调用的结果
由于应用程序递归太深而发生堆栈溢出时引发
建议的解决方案是,删除类B
中对类A
的引用,因为该类未使用:
public class B {
@Override
public String toString() {
return "";
}
}
问题不在于toString
,而在于private B=new B()代码>和私有A=新A()代码>
你正在创造一个创造B的A,创造一个创造B的A,依此类推
stacktrace说的完全一样:B.
表示初始值设定项,而不是toString
。它还指向引发异常的行:B.java:5
和A.java:5
实时代码:
如果您确实需要在B
中按住A
,在A
中按住B
,您可以使用构造函数参数或通过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;
}
}
然后像这样使用它们:
B b = new B();
A a = new A(b);
b.setA(a);
这是一个简化的示例,您可以从中了解情况。在大型应用程序中,如果需要,您可能需要添加生成器、字段/构造函数参数注入或工厂。每个A
在其B
字段中包含一个新的B
。每个B
在其a
字段中包含一个新的a
创建一个新的a
会自动创建一个新的B
,创建一个新的a
,以及另一个新的B
,依此类推,直到堆栈溢出。您的A包含一个B,其中包含一个A,其中包含一个B,其中包含一个A,其中包含一个B,其中包含一个A,其中包含一个B,其中包含一个A,其中包含一个B
未使用B中的A,因此可以将其删除
注意:堆栈跟踪显示问题在构造ie()中,与toString()无关 在此场景中,无论何时创建类A(或B)的对象,只要实例化,它也会创建类B(或B)的新对象。现在,这是一个永无止境的循环,因为无论何时,只要为类a或类B创建一个新对象,另一个类的新对象也会被创建,从而导致对象创建的无限循环。因此,抛出java.lang.StackOverflowerError异常。请随意评论这两个toString()
方法,看看它们是否与问题有关。我找不到重复的堆栈溢出。但这里有一个骗局: