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

posted @ 2014-03-19 20:41  苍枫露雨  阅读(452)  评论(0编辑  收藏  举报