IT懒猫

成功是一个一个步子漫出来的。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

JavaSE知识模糊点----类的初始化顺序问题

Posted on 2013-10-27 13:36  IT懒猫  阅读(321)  评论(0编辑  收藏  举报

  这篇文章将会探讨静态变量、静态代码块、变量、代码块、构造函数的初始化顺序,并了解清楚上述所说的在类的继承情况下的初始化顺序。


 

    测试一

  首先我们先了解单个类中静态变量、静态代码块、变量、代码块、构造函数的初始化顺序

 1 package LianShou;
 2 /**
 3  * 类的初始化顺序测试
 4  * @author Administrator
 5  *
 6  */
 7 public class Test {
 8     //静态变量
 9     static String staticStr="静态变量";
10     //变量
11     String str="变量";
12     //静态代码块
13     static{
14         System.out.println(staticStr);
15         System.out.println("静态代码块");
16     }
17     //代码块
18     {
19         System.out.println(str);
20         System.out.println("代码块");
21     }
22     //构造函数
23     public Test() {
24         System.out.println("构造函数");
25     }
26     /**
27      * main
28      * @param args
29      */
30     public static void main(String[] args) {
31         new Test();
32     }
33 
34 }

输出结果是:静态变量
      静态代码块
      变量
      代码块
      构造函数

所以测试一的结论是:在单个类中,静态变量>静态代码块>变量>代码块>构造函数

    测试二 

看着测试一的结论,静态的大于不静态的大于构造函数,这是毋容置疑的,可是我不禁想问,静态变量是否一定大于静态代码块吗?变量一定大于代码块吗?是否有在源文件中代码先后顺序的影响?

所以我在测试二中放置了两组静态变量和变量的组合,夹住了静态代码块和代码块的组合

package LianShou;

class Obj{
    public Obj(String str){
        System.out.println(str);
    }
}

/**
 * 类的初始化顺序测试
 * @author Administrator
 *
 */
public class Test {
    //静态变量
    static Obj staticObj1=new Obj("静态变量1");
    //变量
    Obj Obj1=new Obj("变量1");
    //静态代码块
    static{
        System.out.println("静态代码块");
    }
    //代码块
    {
        System.out.println("代码块");
    }
    //静态变量
    static Obj staticObj2=new Obj("静态变量2");
    //变量
    Obj Obj2=new Obj("变量2");
    /**
     * main
     * @param args
     */
    public static void main(String[] args) {
        new Test();
    }

}

输出结果是:静态变量1
      静态代码块
      静态变量2
      变量1
      代码块
      变量2

很明显,测试二得出的结论是:静态变量和静态代码块之间,变量和代码块之间,他们相对的出现顺序取决与他们在类中出现的顺序。

至此得出,在单个类中静态变量、静态代码块、变量、代码块、构造函数的初始化顺序为: (静态变量、静态代码块)>(变量、代码块)>构造函数

    测试三 

我们继续了解下在继承的情况下,静态变量、静态代码块、变量、代码块、构造函数的初始化顺序

package LianShou;
/**
 * 类的初始化顺序测试
 * @author Administrator
 *
 */

class Parent {
    //父类静态变量
    static String staticStr="父类静态变量";
    //父类静态代码块
    static{
        System.out.println(staticStr);
        System.out.println("父类静态代码块");
    }
    //父类变量
    String str="父类变量";
    //父类代码块
    {
        System.out.println(str);
        System.out.println("父类代码块");
    }
    //父类构造函数
    public Parent() {
        System.out.println("父类构造函数");
    }

}


public class Test extends Parent {
    //子类静态变量
    static String staticStr="子类静态变量";
    //子类静态代码块
    static{
        System.out.println(staticStr);
        System.out.println("子类静态代码块");
    }
    //子类变量
    String str="子类变量";
    //子类代码块
    {
        System.out.println(str);
        System.out.println("子类代码块");
    }
    //子类构造函数
    public Test() {
        System.out.println("子类构造函数");
    }
    /**
     * main
     * @param args
     */
    public static void main(String[] args) {
        new Test();
    }

}

输出结果是:父类静态变量
      父类静态代码块
      子类静态变量
      子类静态代码块
      父类变量
      父类代码块
      父类构造函数
      子类变量
      子类代码块
      子类构造函数

所以,结合上面测试二得出测试三的结论是: (父类静态变量、父类静态代码块)>(子类静态变量、子类静态代码块)>(父类变量、父类代码块)>父类构造函数>(子类变量、子类代码块)>子类构造函数

这里出现了一个值得注意的地方,那就是,子类的静态变量和静态代码块的初始化在父类的变量和父类代码块和构造函数之前就已经完成了。

好吧,终于收工了。