java-构造函数执行初始化

       今天看到一段很神奇的代码,还没闹明白,先备份一个。

       父类:

      

class SuperClass {

    public int mSuperX = 1;

    public SuperClass(){
    	setX(100);
    }
    
    public SuperClass(int x) {
        setX(x);
    }

    public void setX(int x) {
    	System.out.println("调用了父类的setX方法,赋值为:" + x);
        mSuperX = x;
    }
}

 子类:

class SubClass extends SuperClass {

    public int mSubX = 1;

    public SubClass() {}
    public SubClass(int x) {
    	super(x);
    }

    @Override
    public void setX(int x) {
        super.setX(x);
        mSubX = x;
        System.out.println("调用了子类的setX方法,赋值为:" + x);
    }

    public void printX() {
        System.out.println("SubX = " + mSubX);
    }
}

 测试类:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		 SubClass sc = new SubClass(111);
		 System.out.println(sc.mSuperX);
		 System.out.println(sc.mSubX);
	     sc.printX();
	}

 结果:

调用了父类的setX方法,赋值为:111
调用了子类的setX方法,赋值为:111
111
1
SubX = 1

        很神奇。。。  子类的set赋值方法调用了父类的set方法,然后执行自己的赋值方法。父类的值已经变了,但是子类的值没有变化。。  还是1.  但是,把子类的初始化去掉,改为public int mSubX;执行结果就是正确的111。。

   这就要牵扯到jvm的底层实现了。。。   目前还没搞清楚,只有上网上搜的资料形成自己的理解,不一定对: 

   首先,多态调用的顺序是:1.父类static块 -> 2.子类static块 ->3. 父类普通成员初始化和初始化块 -> 4.父类构造方法 -> 5.子类普通成员初始化和初始化块 -> 6.子类构造方法。

          就像这次遇到的这个问题,把子类的si赋值的语句发生在4,即调用父类构造函数的时候发生的。赋值完成后si的值确实变成了111,但是瞬间,5开始执行,si又被赋值成了1,于是111被覆盖了。

      相当于   int si;   si=1;  中间被插入了si=111;这么个语句。。。

        至于只有int  si的时候,为什么si的值没有被0覆盖。。  网上的说法是静默初始化(即不给值的初始化),在给变量赋值初始化的时候会判断变量是否没有被初始化,即变量不会被初始化两次。。   相当于int si;si=0;这两个语句中间插入了si=111只有,si=0不再执行了。。。   具体再往下深挖就是jvm底层实现的东西了。。。 现在的水平不够。。只能考虑到这了

        

      

猜你喜欢

转载自709002341.iteye.com/blog/2258462