Java的一个栈溢出问题

今天,突然想到这样一个问题,以下代码被调用运行时为何会造成栈溢出(StackOverflowError)的错误:

public class Constructor {
    Constructor c = new Constructor();

    public static void main(String[] args) {
        Constructor test = new Constructor();

    }
}
一般人,初看感觉没啥问题,但是自己在机器上跑了一下,就会爆出这样的错误,如图

 

从这些错误中我们可以得到这样一个信息:程序运行时候,Constructor实例初始化方法,被疯狂的调用。对这个问题的回答,
其中有个网友通过现象推结果,说是:“在这个Constuctor类中,由于类的成员c本身就是Constructor类型的,所以当类的成员初始化时,类的构造函数就被递归调用了”。 这个回答,说实话挺没逻辑的,看的我比较云里雾里。

后面看见有人用反汇编后的该类的字节码入手,就能很清楚的得到问题的答案了.

他用java –p Constructor 得到反汇编后的字节码,如下:
public   class  Constructor  extends  java.lang.Object{
Constructor c;

public  Constructor();
  Code:
    0 :   aload_0
    1 :   invokespecial   # 10 ;  // Method java/lang/Object."<init>":()V
    4 :   aload_0
    5 :    new      # 1 ;  // class Constructor
    8 :   dup
    9 :   invokespecial   # 12 ;  // Method "<init>":()V
    12 :  putfield        # 13 ;  // Field c:LConstructor;
    15 :   return

public   static   void  main(java.lang.String[]);
  Code:
    0 :    new      # 1 ;  // class Constructor
    3 :   dup
    4 :   invokespecial   # 12 ;  // Method "<init>":()V
    7 :   astore_1
    8 :    return
}
我们只要关注此类的构造方法Constructor中的代码就行了,我们可以发现在这构造方法里面,
出现了new #1;//class Constructor 这样的语句,他表示创建一个Constructor类型的对象。从这里面我们便可以明白:
即便你在构造函数外面,显式的初始化了一个成员如c,但是类编译后运行时,这种显式初始化成员的真正初始化还是放在构造函数中,统一进行的。
所以像刚才的那种代码,相当于就是在Constructor构造函数里面调用了自身。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值