定义包含 main() 方法的相同 class 的实例变量时出现 StackOverflowError
Getting StackOverflowError when define instance variable of same class containing main() method
我试图在 google 上搜索答案,但没有找到。为什么下面的程序给出 WhosebugError
.
public class HelloWorld {
private HelloWorld obj = new HelloWorld(); // (HelloWorld.java:2)
public static void main(String args[]) {
HelloWorld obj = new HelloWorld();
obj.printHello();
}
private void printHello(){
System.out.println("Hello world");
}
}
输出:
Exception in thread "main" java.lang.WhosebugError
at HelloWorld.<init>(HelloWorld.java:2)
at HelloWorld.<init>(HelloWorld.java:2)
....................
如果我注释实例变量obj
,那么程序会打印“Hello world”并且没有错误。
见下文:
public class HelloWorld {
// private HelloWorld obj = new HelloWorld();
public static void main(String args[]) {
HelloWorld obj = new HelloWorld();
obj.printHello();
}
private void printHello(){
System.out.println("Hello world");
}
}
输出:
Hello world
循环实例化错误。难怪!
是的,它会抛出 WhosebugException
因为当你这样做时,
HelloWorld obj = new HelloWorld();
在你的 main 中,你的 class 将被初始化 并且它会到达第 2 行,从那里它会尝试再次初始化 HelloWorld
然后它到达第 2 行...循环继续。
这可能会发生即使您的对象不使用相同的名称也是如此。
public class HelloWorld {
private HelloWorld obj = new HelloWorld(); // (HelloWorld.java:2)
public static void main(String args[]) {
HelloWorld obj = new HelloWorld();
obj.printHello();
}
private void printHello(){
System.out.println("Hello world");
}
}
创建 class 的新实例时,就像您在 main 方法中所做的那样:
HelloWorld obj = new HelloWorld();
class 的实例变量的变量初始化器被执行,在 HelloWorld
的情况下,是这里的这一行:
private HelloWorld obj = new HelloWorld(); // (HelloWorld.java:2)
该行创建另一个 HelloWorld
实例,导致同一行再次 运行。要再次 运行 该行,需要创建另一个实例,这意味着同一行必须再次 运行 一次又一次,依此类推...
另一种思考方式是想象 HelloWorld
有一个这样的构造函数:
class HelloWorld {
private HelloWorld obj;
public HelloWorld() {
obj = new HelloWorld();
}
}
你应该清楚地看到无限递归的发生。
如果您查看编译器生成的字节码,您会发现您的代码编译后类似于以下代码。
public class HelloWorld {
private HelloWorld obj; // (HelloWorld.java:2)
public HellowWorld(){
obj = new HelloWorld(); // obj created in the constructor. Point-1
}
public static void main(String args[]) {
HelloWorld obj = new HelloWorld();
obj.printHello();
}
private void printHello(){
System.out.println("Hello world");
}
}
因此,如果您查看第 1 点,您会看到新的 HelloWorld() 调用导致递归调用,没有任何终止条件,这将导致 Whosebug.For 您在下面的参考是字节代码:
public class abc.HelloWorld {
public abc.HelloWorld();
Code:
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #1 // class abc/HelloWorld
8: dup
9: invokespecial #12 // Method "<init>":()V
12: putfield #13 // Field obj:Labc/HelloWorld;
15: return
public static void main(java.lang.String[]);
Code:
0: new #1 // class abc/HelloWorld
3: dup
4: invokespecial #12 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokespecial #20 // Method printHello:()V
12: return
}
我试图在 google 上搜索答案,但没有找到。为什么下面的程序给出 WhosebugError
.
public class HelloWorld {
private HelloWorld obj = new HelloWorld(); // (HelloWorld.java:2)
public static void main(String args[]) {
HelloWorld obj = new HelloWorld();
obj.printHello();
}
private void printHello(){
System.out.println("Hello world");
}
}
输出:
Exception in thread "main" java.lang.WhosebugError
at HelloWorld.<init>(HelloWorld.java:2)
at HelloWorld.<init>(HelloWorld.java:2)
....................
如果我注释实例变量obj
,那么程序会打印“Hello world”并且没有错误。
见下文:
public class HelloWorld {
// private HelloWorld obj = new HelloWorld();
public static void main(String args[]) {
HelloWorld obj = new HelloWorld();
obj.printHello();
}
private void printHello(){
System.out.println("Hello world");
}
}
输出:
Hello world
循环实例化错误。难怪!
是的,它会抛出 WhosebugException
因为当你这样做时,
HelloWorld obj = new HelloWorld();
在你的 main 中,你的 class 将被初始化 并且它会到达第 2 行,从那里它会尝试再次初始化 HelloWorld
然后它到达第 2 行...循环继续。
这可能会发生即使您的对象不使用相同的名称也是如此。
public class HelloWorld {
private HelloWorld obj = new HelloWorld(); // (HelloWorld.java:2)
public static void main(String args[]) {
HelloWorld obj = new HelloWorld();
obj.printHello();
}
private void printHello(){
System.out.println("Hello world");
}
}
创建 class 的新实例时,就像您在 main 方法中所做的那样:
HelloWorld obj = new HelloWorld();
class 的实例变量的变量初始化器被执行,在 HelloWorld
的情况下,是这里的这一行:
private HelloWorld obj = new HelloWorld(); // (HelloWorld.java:2)
该行创建另一个 HelloWorld
实例,导致同一行再次 运行。要再次 运行 该行,需要创建另一个实例,这意味着同一行必须再次 运行 一次又一次,依此类推...
另一种思考方式是想象 HelloWorld
有一个这样的构造函数:
class HelloWorld {
private HelloWorld obj;
public HelloWorld() {
obj = new HelloWorld();
}
}
你应该清楚地看到无限递归的发生。
如果您查看编译器生成的字节码,您会发现您的代码编译后类似于以下代码。
public class HelloWorld {
private HelloWorld obj; // (HelloWorld.java:2)
public HellowWorld(){
obj = new HelloWorld(); // obj created in the constructor. Point-1
}
public static void main(String args[]) {
HelloWorld obj = new HelloWorld();
obj.printHello();
}
private void printHello(){
System.out.println("Hello world");
}
}
因此,如果您查看第 1 点,您会看到新的 HelloWorld() 调用导致递归调用,没有任何终止条件,这将导致 Whosebug.For 您在下面的参考是字节代码:
public class abc.HelloWorld {
public abc.HelloWorld();
Code:
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #1 // class abc/HelloWorld
8: dup
9: invokespecial #12 // Method "<init>":()V
12: putfield #13 // Field obj:Labc/HelloWorld;
15: return
public static void main(java.lang.String[]);
Code:
0: new #1 // class abc/HelloWorld
3: dup
4: invokespecial #12 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokespecial #20 // Method printHello:()V
12: return
}