Java初始化顺序

来源:互联网 发布:ansys软件配置要求 编辑:程序博客网 时间:2024/05/22 05:14
  • 问题描述:Java在初始化过程中涉及很多考虑因素,静态块、静态数据、父类子类构造器等,这两天重看《Java编程思想》这本书时,写了个简单的“DEMO”整理了一下,希望能将整个过程说的明晰,也留给自己以后便于回顾。

  • 代码测试:

class Something{    public Something(String string){        System.out.println(string);    }}class Parent{    static{        System.out.println("父类静态块");    }    static private Something thing1=new Something("父类静态成员");    private Something thing2=new Something("父类普通成员");    public Parent(){        System.out.println("父类构造器");    }}class Child extends Parent{    static{        System.out.println("子类静态块");    }    static private Something thing3=new Something("子类静态成员");    private Something thing4=new Something("子类普通成员");    public Child(){        System.out.println("子类构造器");    }}public class Test{    static private Something thing5=new Something("“Test”静态成员");    private Something thing6=new Something("“Test”普通成员");    public static void main(String[] args){        System.out.println("进入“main”函数");        new Child();        new Test();    }}
  • 运行结果:

    测试代码运行结果

    (结果图)

  • DEMO解析:

    • 编译器加载“Test”类时,首先初始该类下的“Static”成员,输出图片的第一行信息,然后进入同为“static”的“main”函数,输出第二行信息;

    • 需要生成“Child”对象时,编译器开始加载“Child”类,此时遇到“extends”关键字,则转而向上加载父类“Parent”;

    • 从图片的“3、4、5、6”行可看出,首先加载父类静态块、父类静态成员,再转到子类加载子类的静态块、子类静态成员。待父类、子类都加载完“static”域后,开始构造子类对象;

    • 首先是父类普通成员的初始化,有初始值的赋予初始值,无初始值的赋予默认初始值(引用为“null”,基本类型为“0”或“false”),然后调用父类构造器;

    • 父类部分完成初始化后,子类普通成员开始初始化,接着调用子类构造器(这里说一下为什么父类必须先于子类初始化,因为子类继承父类的所有数据,假设子类变量“a”在构造器中依赖于父类变量“b”来进行构造,例如“a=b+1”,那么变量“b”必须是已经具有初始化的数据);

    • “new Test()”可以看出,普通成员是否需要初始化取决于是否需要创建该类型的对象。

  • 问题总结:

    • 我们在命令行下运行“.class”文件时,调用的哪个类的“.class”文件,就从哪个类开始初始化;

    • 首先编译该类的所有“static”静态块,然后按照从上到下的顺序依次编译各个“static”数据成员,最后进入“main”方法;

    • 构造一个对象时,若该对象对应的类有父类,则顺序为:先父类“static”,再子类“static”(每个类中的“static”顺序同上一条),然后父类普通成员初始化、父类构造器,最后子类普通成员初始化、子类构造器;

  • 写到最后:以上所述即为目前所能遇到的大部分初始化情况,以后若遇到个例再进行补充。

0 0