zoukankan      html  css  js  c++  java
  • java类的初始化顺序

    java类的初始化顺序

    (2008-10-21 13:30:15)
    标签:

    java

    初始化

    继承初始化

    it

    分类: Java
    对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点:

    public class InitialOrderTest {
    // 静态变量
    public static String staticField = "静态变量";
    // 变量
    public String field = "变量";
    // 静态初始化块
    static {
    System.out.println(staticField);
    System.out.println("静态初始化块");
    }

    // 初始化块
    {
    System.out.println(field);
    System.out.println("初始化块");
    }

    // 构造器
    public InitialOrderTest() {
    System.out.println("构造器");
    }
    public static void main(String[] args) {
    new InitialOrderTest();
    }
    }
    运行以上代码,我们会得到如下的输出结果:
    1. 静态变量
    2. 静态初始化块
    3. 变量
    4. 初始化块
    5. 构造器

    这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果:
    class Parent {
     // 静态变量
     public static String p_StaticField = "父类--静态变量";
     // 变量
     public String p_Field = "父类--变量";
     protected int i = 9;
     protected int j = 0;
     // 静态初始化块
     static {
      System.out.println(p_StaticField);
      System.out.println("父类--静态初始化块");
     }
     // 初始化块
     {
      System.out.println(p_Field);
      System.out.println("父类--初始化块");
     }
    // 构造器
     public Parent() {
      System.out.println("父类--构造器");
      System.out.println("i=" + i + ", j=" + j);
      j = 20;

     }
    }

    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("子类--构造器");
      System.out.println("i=" + i + ",j=" + j);
     }
    // 程序入口
     public static void main(String[] args) {
      System.out.println("子类main方法");
      new SubClass();
     }
    }
    运行一下上面的代码,结果马上呈现在我们的眼前:
    父类--静态变量
    父类--静态初始化块
    子类--静态变量
    子类--静态初始化块
    子类main方法
    父类--变量
    父类--初始化块
    父类--构造器
    i=9, j=0
    子类--变量
    子类--初始化块
    子类--构造器
    i=9,j=20
    现在,结果已经不言自明了。子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。
    静态变量、静态初始化块,变量、初始化块初始化了顺序取决于它们在类中出现的先后顺序。

    执行过程分析

     (1)访问SubClass.main(),(这是一个static方法),于是装载器就会为你寻找已经编译的SubClass类的代码(也就是SubClass.class文件)。在装载的过程中,装载器注意到它有一个基类(也就是extends所要表示的意思),于是它再装载基类。不管你创不创建基类对象,这个过程总会发生。如果基类还有基类,那么第二个基类也会被装载,依此类推。

    (2)执行根基类的static初始化,然后是下一个派生类的static初始化,依此类推。这个顺序非常重要,因为派生类的“static初始化”有可能要依赖基类成员的正确初始化。

    (3)当所有必要的类都已经装载结束,开始执行main()方法体并用new SubClass()创建对象。

    (4)类SubClass存在父类,则调用父类的构造函数,你可以使用super来指定调用哪个构造函数(也就是Beetle()构造函数所做的第一件事)。

    基类的构造过程以及构造顺序,同派生类的相同。首先基类中各个变量按照字面顺序进行初始化,然后执行基类的构造函数的其余部分。

    (5)对子类成员数据按照它们声明的顺序初始化,执行子类构造函数的其余部分。

  • 相关阅读:
    MKMapVIew学习系列2 在地图上绘制出你运行的轨迹
    WPF SDK研究 Intro(6) WordGame1
    WPF SDK研究 Intro(3) QuickStart3
    WPF SDK研究 Layout(1) Grid
    WPF SDK研究 目录 前言
    WPF SDK研究 Intro(7) WordGame2
    WPF SDK研究 Layout(2) GridComplex
    对vs2005创建的WPF模板分析
    WPF SDK研究 Intro(4) QuickStart4
    《Programming WPF》翻译 第6章 资源
  • 原文地址:https://www.cnblogs.com/dragon-zhong/p/4787479.html
Copyright © 2011-2022 走看看