Java对象加载(初始化)顺序

来源:互联网 发布:矩阵式项目组织形式 编辑:程序博客网 时间:2024/05/21 14:46

Java对象加载初始化顺序

利用测试类进行研究、请注意打印结果。

父类设计:

package com.ibm.dietime1943.mars;public class Father {public static int f = 100;static{System.out.println("加载: 父类 static块、在这之前乱入了父类静态变量Σ( ° △ °|||)  ︴" + f);}public Father(){System.out.println("加载: 父类 构造器");}{System.out.println("加载: 父类 非static块");}}

子类设计:

package com.ibm.dietime1943.mars;public class Son extends Father{public static int s = 99;private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}static{System.out.println("加载: 子类 static块、在这之前乱入了子类静态变量^(*(oo)*)^   ︴" + s);}public Son(){System.out.println("加载: 子类 构造器");}{System.out.println("加载: 子类 非static块");}}

测试类设计:

package com.ibm.dietime1943.mars;public class Test {public static void main(String[] args) {Son son = new Son();son.setName("程序");System.out.println(son.getName() + ": 执行完了");}}

打印结果:


总结:

1、对象加载的大致顺序如下:
    .在一个不存在继承的类中:初始化static变量 → 执行static初始化快 → 初始化普通成员变量(如果有赋值语句) → 执行普通初始化块 → 构造方法
    .在一个存在继承的类中:初始化父类static成员变量 → 运行父类static初始化块 → 初始化子类static成员变量 → 运行子类static初始化块 → 初始化父类实例成员变量(如果有赋值语句) → 执行父类普通初始化块 →父类构造方法 → 初始化子类实例成员变量(如果有赋值语句)及普通初始化块 → 子类构造方法

   補足:为什么父类构造器先加载、子类的构造器后加载(构造器的加载顺序父类的优先级大于子类)?// 2016/12/21 18:55 Tata 追記

   当进行继承时、我们已经知道了基类的一切、并且可以访问基类中任何声明为public和protected的成员。这也意味着在导出类中、必须假定基类的所有成员都是有效的。一种标准方法是、构造动作一经发生、那么对象所有部分的全体成员都会得到构建。然而在构造器内部、我们必须确保所要使用的成员都已经构造完毕。为确保这一目的、唯一的办法就是首先调用基类的构造器。// <<Java编程思想>>第

TODO。

Java中实例子类会有父类对象产生吗 //fixme 2016年12月23日17:00:28。

TODO。

2、static相关:
    .static成员变量可以再定义的时候初始化也可以在static块中初始化、static块可以出现多次、当编译成.class文件时会将多个static块的内容合并;实例成员变量可以再定义时初始化也可以在普通初始化块或构造函数中初始化。
    ❷.基本数据类型的成员变量要在初始化后再使用、引用数据类型的成员变量在实例化后才能被使用。
3、类的加载时机:
    .用new创建该类的实例时
    .使用java.lang.reflect进行反射调用的时
    .之前没有加载该类,之后加载该类的子类的时
    .当虚拟机启动时,初始化main函数所在的类
JVM载入类时会执行static块、创建一个实例时会运行构造方法。static块和static成员变量都是属于类而非实例的;构造函数和普通成员变量是属于一个实例的。类的初始化(包括static块的运行和static成员变量的赋值)只运行一次、多次创建某个类的实例只会运行一次该类的static{}块、但会运行多次其构造函数。




Flag Counter

1 0