当创建任何Java对象时,程序总会先依次调用每个父类的静态代码块,之后在依次调用代码块,父类构造器执行初始化,最后才调用本类的代码块,构造器执行初始化。
public class StudyJavaInit {public static void main(String[] args) {Son son = new Son();}}class Person{static String sex = "男";{String action = "eat";System.out.println("Person 类的代码块初始值的action:" + action);}static{System.out.println("Person 类的静态代码块初始值的sex:" + sex);String sex = "女";System.out.println("Person 类的静态代码块重新赋值后的sex:" + sex);}String action = "sleep";public Person() {System.out.println("Person 类的无参构造器");}public Person(String age) {this(); // 显示调用无参构造器System.out.println("Person 类的一个参数构造器");}@Overridepublic String toString() {return "Person{" +"action='" + action + '\'' +'}';}}class Parent extends Person{static String sex = "男";static{System.out.println("Parent 类的静态代码块初始值的sex:" + sex);String sex = "女";System.out.println("Parent 类的静态代码块重新赋值后的sex:" + sex);}{String action = "eat";System.out.println("Parent 类的代码块初始值的action:" + action);}String action = "sleep";public Parent(String age, String name) {this(name); // 显示调用Parent一个参数构造器System.out.println("Parent带两个参数构造器");}public Parent(String name) {super(name); // 显示调用Parent一个参数构造器System.out.println("Parent带一个参数构造器");}}class Son extends Parent{static String sex = "男";String action = "sleep";{System.out.println("Son 类的代码块初始值的action:" + action);String action = "eat";System.out.println("Son 类的代码块重新赋值后值的action:" + action);}static{System.out.println("Son 类的静态代码块初始值的sex:" + sex);String sex = "女";System.out.println("Son 类的静态代码块重新赋值后的sex:" + sex);}public Son() {super("java");System.out.println("Son 的无参构造器");}public Son(String name) {this();System.out.println("Son 带一个参数构造器");}}执行结果:Person 类的静态代码块初始值的sex:男Person 类的静态代码块重新赋值后的sex:女Parent 类的静态代码块初始值的sex:男Parent 类的静态代码块重新赋值后的sex:女Son 类的静态代码块初始值的sex:男Son 类的静态代码块重新赋值后的sex:女Person 类的代码块初始值的action:eatPerson 类的无参构造器Person 类的一个参数构造器Parent 类的代码块初始值的action:eatParent带一个参数构造器Son 类的代码块初始值的action:sleepSon 类的代码块重新赋值后值的action:eatSon 的无参构造器
所以只要在程序创建Java对象,系统总是先依次执行完父类静态代码块,然后调用最顶层父类初始化操作,包括初始化块和构造器,最后依次向下调用所有父类的初始化操作,最终执行本类的初始化操作返回本类的实例。
至于调用父类的哪个构造器执行初始化,则分为以下几种情况
1.子类构造器执行体的第一行代码使用super显示调用父类构造器,系统根据super里的传入的实参数来调用父类哪个构造器
2.子类构造器执行体的第一行代码使用this显示调用本类中重载的构造器,系统根据this里的传入的实参数来调用本类另一个重载构造器
3.子类构造器执行体中既没有super调用,也没有this调用,系统将会在执行子类构造器之前,隐式调用父类无参数的构造器
需要注意的式super调用用于显示调用父类的构造器,this调用用于显示调用本类中另一个重载构造器。super调用和this调用都只能在构造器中使用,而且super调用和this调用都必须作为构造器的第一行代码,因此构造器中的super调用和this调用最多只能使用其中之一,而且最多只能调用一次。
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦