class Demo {
Demo d = new Demo();
}
class Test {
Demo d = new Demo();//编译通过
main() {
new Demo();//堆栈溢出
}
}
如上代码 ,为什么Test类main方法中的会报错,但是成员中的编译通过呢
你要问的应该是为什么编译能通过.但还是堆栈溢出了.
编译:只是检测语法问题.你这个是逻辑BUG.编译器检查不出来的.必须要运行起来才能知道会溢出.
编译的时候并没有运行.
你需要搞清楚2个时间:编译时,运行时.就像宏命令只是编译时生效一样.宏命令属于编译时.而这种代码运行时才会抛出的bug.属于运行时.编译器无能为力
就是说为什么会发生递归 能跟我解释一下吗 看这楼上加了静态为什么不会递归呢?
@皇城飞雪: 上面不是不会递归.是不会执行...你都没认真看我的回答...
new一个对象时会执行他的构造函数.你在构造函数里new对象当然就会new一个对象时会执行他的构造函数然后new一个对象时会执行他的构造函数再然后new一个对象时会执行他的构造函数
@吴瑞祥: demo类的默认构造方法不是空的吗,不是因为实例化demo类的对象这条语句是因为创建a对象初始化不停调用产生的递归吗?不好意思因为刚学JAVA,不是很懂,static修饰后为什么不会执行,主函数不也是静态的吗
@皇城飞雪:
1.静态变量在被调用时才会初始化.
2.字段初始化只是一个语法糖.他最终会变编译到构造函数里.
买本语法书吧...不然还会有更多这种问题的.比如父类的静态泛型字段.在何时被初始化.在不同泛型子类中是否是同一个值.
因为你在Demo类中递归实例引用了,所以new的时候会爆栈,改成如下:
class Demo {
static Demo d = new Demo();
}
不好意思 这个递归是怎么发生的 很多人都跟我这么解释,搞不太懂
递归引用,栈溢出。
IDE只检测编译期错误,运行时错误,如楼上所说,无能为力。
一直new下去?
解释一下为什么会溢出吧:
一个类实例化的时候,会先运行其成员变量的语句。即你在Test类中调用new Demo()的时候,实例化这个Demo的时候,会先执行Demo类中的Demo d = new Demo()这一句,这时候又要求实例化Demo, 此时又要先执行Demo d = new Demo(), 然后又要求实例化Demo...... 这样就形成了死循环,最终溢出。