关于JAVA继承类的静态变量、成员变量、父子类构造方法调用顺序的探讨 .

综合网上的相关帖子和我自己的调试,研究了一下关于JAVA继承类的静态变量、成员变量、父子类构造方法调用顺序问题。首先看一段程序:

class X {
    Y b
=new Y();//7、这里是父类成员变量初始化
    static Y sb=new Y();//1、父类静态变量,输出static Y(静态代码块先初始化),2、Y

   
static{
        System.out.println(
"static X父类静态代码块");//3、执行静态代码块
        new Y();//4、这里只是输出Y,有static Y(静态代码块只执行一次)
    }
    X() {

        System.out.println("X");//8、父类成员变量初始化之后,执行父类构造器输出X
    }
}

class Y {
   
static{
        System.out.println(
"static Y");       
    }
    Y() {
//执行构造函数
       
//这里有个super()==Object()
        System.out.println("Y");
    }
}

publicclass Z extends X {
   
finalstaticint mead=45;
   
finalbyte b=16;
   
static Y sb=new Y();//5、子类的静态变量,输出Y
    static{      
        System.out.println(
"static Z");//6、子类的静态代码块
    }
    Y y
=new Y();//9、这里是子类成员变量初始化

    Z() {
       
//这里有super()==new X()
        this.y =null;
        System.out.println(
"Z");//10、子类成员变量初始化之后,执行子类构造器输出Z
    }

   
publicstaticvoid main(String[] args) {
       
new Z();

    }
}

执行结果:

static Y
Y
static X父类静态代码块
Y
Y
static Z
Y
X
Y
Z

解释:
static的东西在编译的时候就向内存要到了存取空间,他们的初始化要早于非static,顺序是先父类再子类。
初始化类,先执行super()父类的的构造函数(final和static之后),父类的构造函数先执行super()直到object super(),完了执行一般成员变量的初始化

一般成员变量初始化完毕,执行构造器里面的代码(super()之后的代码).
父类的初始化完成后(子类构造器里面super执行完毕),才轮到子类的成员变量初始化
子类成员变量初始化完毕,开始执行子类构造器里面的代码(super()之后的代码).

注意:

静态块和静态变量的调用顺序是按照书写顺序执行的,比如上边X类中静态块和静态变量的书写顺序颠倒如下:

class X {
  Y b = new Y();
       static{
        System.out.println("static X父类静态代码块");
        new Y();
    }
    static Y sb= new Y();
    X() {
        System.out.println("X");
    }
  
}

则执行结果为:

static X父类静态代码块
static Y
Y
Y
Y
static Z
Y
X
Y
Z

最后:

确定变量空间和初始化赋值是分开进行的,先一次性确定静态成员变量空间 并赋给二进制0 ,然后按照书写顺序逐一赋值

如下代码,输出结果是0.0

publicclass Test {
   
staticint i=f();
   
staticdouble d=0.1234;
   
publicstaticvoid main(String[] args) {
       
new Test();
    }
   
staticint f(){
        System.out.println(d);
       
return3;
    }
}

原址:

http://blog.csdn.net/pisota/article/details/5332848

原文地址:https://www.cnblogs.com/edison2012/p/2834958.html