JAVA变量的执行顺序
对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点:
package InitialOrder; /** * JAVA 初始化顺序 * @author Administrator * 初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)> 构造器。 */ public class InitialOrderTest { // 静态变量 public static String staticField = "静态变量"; // 变量 public String field = "变量"; // 构造器 public InitialOrderTest() { System.out.println("构造器"); } // 初始化块 { System.out.println(field); System.out.println("初始化块"); } // 静态初始化块 static { System.out.println(staticField); System.out.println("静态初始化块"); } public static void main(String[] args) { new InitialOrderTest(); } /** * 输出结果为: * 静态变量 * 静态初始化块 * 变量 * 初始化块 * 构造器 */ }
对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果:
package InitialOrder; class Parent { // 静态变量 public static String p_StaticField = "父类--静态变量"; // 变量 public String p_Field = "父类--变量"; // 构造器 public Parent() { System.out.println("父类--构造器"); } // 初始化块 { System.out.println(p_Field); System.out.println("父类--初始化块"); } // 静态初始化块 static { System.out.println(p_StaticField); System.out.println("父类--静态初始化块"); } } /** * 对于继承情况下,静态变量、静态初始化块、变量、初始化块、构造器的执行顺序是什么样的呢? * @author Administrator * 并不是父类完全初始化完毕后才进行子类的初始化, * 实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。 * */ public class SubClass extends Parent { // 静态变量 public static String s_StaticField = "子类--静态变量"; // 变量 public String s_Field = "子类--变量"; // 构造器 public SubClass() { System.out.println("子类--构造器"); } // 初始化块 { System.out.println(s_Field); System.out.println("子类--初始化块"); } // 静态初始化块 static { System.out.println(s_StaticField); System.out.println("子类--静态初始化块"); } // 程序入口 public static void main(String[] args) { new SubClass(); } /** * 输出结果: * 父类--静态变量 * 父类--静态初始化块 * 子类--静态变量 * 子类--静态初始化块 * 父类--变量 * 父类--初始化块 * 父类--构造器 * 子类--变量 * 子类--初始化块 * 子类--构造器 */ }
现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。
那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明:
package InitialOrder; class TestA { public TestA() { System.out.println("Test--A"); } } class TestB { public TestB() { System.out.println("Test--B"); } } /** * 对于静态变量与静态初始化块的执行顺序 * @author Administrator * 静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。 * 同样,变量和初始化块也遵循这个规律。 */ 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(); } /** * 输出结果: * Test--A * 静态初始化块 * Test--B */ }
大家可以随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。
参考资料:
http://my.oschina.net/leoson/blog/103251