我发现了个Java陷阱,虽说我自己知道了这是为什么,但是,在CSDN群里发布下,有兴趣的可回答,
答对给分:
public class A{
private A a = new A();
public A(){
System.out.println("你好!");
}
}
//测试类
public class test {
public static void main(String[] args) {
A s = new A();
}
}请问,1、程序的结果是什么?2、为什么?
答对给分:
public class A{
private A a = new A();
public A(){
System.out.println("你好!");
}
}
//测试类
public class test {
public static void main(String[] args) {
A s = new A();
}
}请问,1、程序的结果是什么?2、为什么?
class A{
A a = null;
public A() throws InterruptedException{
Thread.sleep(1000);
System.out.println("-----");
a = new A();
System.out.println("hello");
}
}public class Test {
public static void main(String[] args) throws InterruptedException {
A a = new A();
}
}改成了这样。成员变量初始化赋值相当于是在构造方法中赋值。构造方法不断调用构造方法,成了死循环,然后栈溢出了。。
兄弟,我知道你厉害!
我可以告诉你我是故意这么写的么?
如果你真有这么强,这个简单的问题应该小case,那请问,为什么呢 ?
放到楼主这里的运行顺序就是new A的时候初始化里面的成员变量a,但a又进行了A的实例化那么又要来一遍初始化A,也是一样的先初始化成员变量a,但a又进行了A的实例化那么又要来一遍初始化A。就这样无限递归下去了
不过,作为发问者,我自己提出个跟你不一样的结论:VM在处理时,有如下方式,请看
Compiled from "test.java"
public class test extends java.lang.Object{
public test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: returnpublic static void main(java.lang.String[]);
Code:
0: new #2; //class Singleton
3: dup
4: invokespecial #3; //Method Singleton."<init>":()V
7: astore_1
8: return}
执行到astore_1时,从栈顶弹出一个引用类型,或某个引用的地址弹出,然后存入索引为1的指定的局部变量中,并即将开始,引用该局部。所以会发生无限递归,却又无法进入构造块里面,无法结束构造!所以看似简单的构造函数,却因为如此,进入了死循环!很多人说进入了无限递归,我不赞同,个人认为,因为根本没有进入函数内部,只是简单的加载而已,何来递归?就是个死循环!