java基础之——类的初始化顺序

由浅入深,首先,我们来看一下,一个类初始化有关的都有些啥米:

  静态成员变量、静态代码块、普通成员变量、普通代码块、构造器。(成员方法?貌似跟初始化没有啥关系)

现在我们来看看她们的初始化顺序,

  从性质上来说,静态的代表的是一个类的属性,普通的是一个对象的属性,“皮之不存,毛将焉附”,没有类,就没法谈对象,所以静态的必须先初始化。

那么静态成员变量与静态代码块之间又是什么关系呢?

  做了个实验,发现静态成员变量与静态代码块谁放前面谁先执行,但是!!!!注意!!!!这里说的是“执行”是指的把sx=10,这个10赋给sx,而不是sx的初始化,在实验2里在代码块中打断点,可以发现这个时候sx已经被初始化为0,这里我是这样理解:既然在初始化这个类(或对象)的成员了,那说明已经给它分配好内存了,int分配好内存后默认值为0(基础类型的默认值有false,0,null),不知道这么理解对不对。所以最终的结论是,先初始化成员变量为默认值,然后根据成员变量与代码块的先后顺序进一步初始化。

实验代码如下:

//实验1
private
static int sx = 10; static{ System.out.println("execute static block"); } 与
//实验2
static{ System.out.println("execute static block"); } private static int sx = 10;

  接着说,普通成员变量与普通代码块和静态的一个道理,就不累述了。

那么构造器与普通成员变量和普通代码块的关系呢?

  这个我是通过实验得了这么个结论,是成员变量的"=xxx"(和成员变量初始化为默认值区分)和代码块先执行,然后再执行构造器中的。(实验代码最后一并贴出)

 

 

ok到这里为止,一个类的我们简单的说完了,那么类还有继承呢,子类和父类结合到一起的时候又是什么一个顺序呢?

其实挺简单的,子类继承自父类,可以使用父类的非private成员,所以,在在初始化子类之前肯定是要先初始化父类。

 

 

最终的顺序是:

父类静态成员变量初始化为默认值—>

子类静态成员变量初始化为默认值—>

父类按出现的先后顺序执行静态成员变量的“=xxx”和静态代码块—>

子类的按出现的先后顺序执行静态成员变量的“=xxx”和静态代码块—>

父类普通成员变量初始化为默认值—>

子类普通成员变量初始化为默认值—>

父类按出现的先后顺序执行普通成员变量的“=xxx”和静态代码块—>

父类执行构造函数—>

子类的按出现的先后顺序执行普通成员变量的“=xxx”和静态代码块—>

子类执行构造函数—>end

 

实验代码:

package abstractClass;



@SuppressWarnings("unused")

abstract class AbstractDemo {

    {

        System.out.println("execute super block,this.x="+this.x);

    }

    static{

        System.out.println("execute static super block,this.sx="+AbstractDemo.sx);

    }

    public static int SuperPS = 1;

    private static int sx = 1;

    private int x = 1;



    public AbstractDemo(){

        super();

        System.out.println("execute super constractor");

//        this.print();

    }

    

    public abstract void print();

}



@SuppressWarnings("unused")

class DemoImpl extends AbstractDemo{

    public static int PS = 10;

    private static int sx = 10;

    private int x = 10;   //从调试的结果来看,此处是在执行完super()之后执行,然后再接着执行构造器

    {

        System.out.println("execute block,this.x="+this.x);

    }

    static{

        System.out.println("execute static block,this.sx="+DemoImpl.sx);

    }

    public DemoImpl(int x){

        super();  //断点

        System.out.println("execute constractor");

        System.out.println("before init in constractor this.x="+this.x);

        this.x = x;

    }

    

    @Override 

    public void print(){

        System.out.println("this.x="+x);

    }

}



public class TestAbstractDemo{

    public static void main(String[] args) {

        new DemoImpl(100);

    }

}

实验结果:

execute static super block,this.sx=0
execute static block,this.sx=10
execute super block,this.x=0
execute super constractor
execute block,this.x=10
execute constractor
before init in constractor this.x=10

你可能感兴趣的:(java基础)