运行此代码时,它显示Stackoverflow错误。我做错了什么,代码为什么要编译?
public class Foo {
int a = 5;
Foo f = new Foo();
void go() {
System.out.println(f.a);
}
public static void main(String[] args) {
Foo f2 = new Foo();
f2.go();
}
}
答案 0 :(得分:7)
Foo f=new Foo();
您创建了一个Foo
实例,其中一个变量本身就是Foo
的一个实例,并在构造函数中初始化它。
这会导致构造函数invokations的无限递归,直到你的堆栈空间不足。
答案 1 :(得分:4)
这是您的f
初始化程序:
public class Foo {
int a=5;
Foo f=new Foo();
每当构建新的Foo
时,作为初始化的一部分,它会尝试创建Foo
并将其分配给f
。但显然,构建Foo
会再次启动整个过程。
答案 2 :(得分:3)
当程序执行开始时,控制进入main方法,找到Foo f2 = new Foo()。它创建了Foo的对象,在创建对象时,它必须实例化包含Foo f = new Foo()的所有实例变量,因此它再次创建一个新的Foo对象并加载所有实例变量,并且它也找到相同的Foo f = new Foo(),所以它再次创建Foo对象,这将继续,直到堆栈溢出。
这可以通过改变来解决 Foo f = new Foo(); 至 Foo f = null;
答案 3 :(得分:1)
这基本上是您question from an hour ago的重新发布。请花时间了解人们给你的答案。
您的代码与:
相同public class Foo {
Foo f = null;
public Foo() {
this.f = new Foo(); // recursion here
}
//do your other stuff
}
}
答案 4 :(得分:1)
您只能使用实例调用go
方法。因此,在开始致电之前,c'tor已经参加了课程Foo
现在,C'tor旨在初始化所有实例成员。
所以一个接一个地初始化:
a初始化为5
f被初始化为一个对象//但这里是catch,f永远不会被启动。
在=
运算符工作之前,C'tor被调用,因此链继续。
如果您看到堆栈跟踪,则会在其中写入init
。所以它只在初始化期间失败。