类的初始化顺序

        我们接触Java初期会困扰这样一个问题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台的代码,然后让我们判断输出的结果。
        先看一段代码,分析下打印结果
public class InitBeanTest {
    // 静态变量
    public static String staticField = "静态变量";
    // 变量
    public String field = "变量";
    // 初始化块
    {
        System.out.println(field);
        System.out.println("初始化块");
    }
    // 静态初始化块
    static {
        System.out.println(staticField);
        System.out.println("静态初始化块");
    }
    // 构造器
    public InitBeanTest() {
        System.out.println("构造器");
    }
    public static void main(String[] args) {
        new InitBeanTest();
    }
}

结果:

 

         我们可以得出结论:对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。

 

         如果类之间存在继承关系结果会有什么不同,写一段测试代码

父类:Parent

class Parent {
// 静态变量
public static String p_StaticField = "父类--静态变量";
// 变量
public String p_Field = "父类--变量";
// 静态初始化块
static {
System.out.println(p_StaticField);
System.out.println("父类--静态初始化块");
}
// 初始化块
{
System.out.println(p_Field);
System.out.println("父类--初始化块");
}
// 构造器
public Parent() {
System.out.println("父类--构造器");
} }

子类:Subclass

public class SubClass extends Parent {
// 静态变量
public static String s_StaticField = "子类--静态变量";
// 变量
public String s_Field = "子类--变量";
// 静态初始化块
static {
System.out.println(s_StaticField);
System.out.println("子类--静态初始化块");
}
// 初始化块
{
System.out.println(s_Field);
System.out.println("子类--初始化块");
}
// 构造器
public SubClass() {
System.out.println("子类--构造器");
}
// 程序入口
public static void main(String[] args) {
new SubClass();
} }

结果:

          结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。
         
          那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。
          测试代码
public class TestOrder {
// 静态变量
public static TestA a = new TestA();
// 静态初始化块
static {
System.out.println("静态初始化块");
}
// 静态变量
public static TestB b = new TestB();
public static void main(String[] args) {
new TestOrder();
} }
class TestA {
public TestA() {
System.out.println("Test--A");
} }
class TestB {
public TestB() {
System.out.println("Test--B");
} }

结果:

           随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。
posted @ 2019-07-22 15:45  Don'tYouSee  阅读(150)  评论(0编辑  收藏  举报