执行时,下面的代码会产生堆栈溢出错误.但是,如果删除其中之一
static final GenerateStackOverflow E1 = new GenerateStackOverflow("value1");final GenerateStackOverflow E2 = new GenerateStackOverflow("value2");它在没有堆栈溢出错误的情况下运行.如果我有上面的两行,怎么会出现堆栈溢出错误,但如果只有一行是在类中,则没有错误?
public class GenerateStackOverflow {
private final String value;
static final GenerateStackOverflow E1 = new GenerateStackOverflow("value1");
final GenerateStackOverflow E2 = new GenerateStackOverflow("value2");
public GenerateStackOverflow(String value) {
System.out.println("GenerateStackOverflow.GenerateStackOverflow()");
this.value = value;
}
public String getValue() {
return value;
}
public static void main(String[] args) {
GenerateStackOverflow.class.getName();
}
}
Run Code Online (Sandbox Code Playgroud)
两者都需要生成一个StackOverflowError.当您包含此行时:
static final GenerateStackOverflow E1 = new GenerateStackOverflow("value1");
Run Code Online (Sandbox Code Playgroud)
GenerateStackOverflow如果首次访问该类,则会创建一个实例.
没有这一行包括:
final GenerateStackOverflow E2 = new GenerateStackOverflow("value2");
Run Code Online (Sandbox Code Playgroud)
事情很好.但这条线很重要.每次GenerateStackOverflow创建实例时,它都会尝试初始化其成员变量E2- 另一个GenerateStackOverflow对象.然后该实例将其 E2初始化为另一个GenerateStackOverflow对象.这一直持续到StackOverflowError发生.
如果包含第二行但第一行不包含,则不会创建任何实例,并且永远不会输入无限递归.
构造函数调用自身:
final GenerateStackOverflow E2 = new GenerateStackOverflow("value2");
Run Code Online (Sandbox Code Playgroud)
因此,要构造一个实例,您需要构造一个需要构造实例的实例,等等.
你的程序的main方法加载了这个类.并且有一个静态字段调用类的构造函数,这会创建堆栈溢出.因此,删除静态变量会隐藏问题,因为永远不会调用构造函数.删除非静态变量会完全删除递归调用,从而修复了probem.
| 归档时间: |
|
| 查看次数: |
148 次 |
| 最近记录: |