參考書籍:《編寫高質(zhì)量代碼:改善Java程序的151個(gè)建議》
很久以前寫過一篇文章:Java類初始化加載過程,只是暴力的根據(jù)打印順序判斷構(gòu)造代碼塊和構(gòu)造函數(shù)的先后執(zhí)行順序,卻沒提及其原因。那么,為什么構(gòu)造代碼塊先于構(gòu)造函數(shù)執(zhí)行呢?
因?yàn)榫幾g器會把構(gòu)造代碼塊插入到不含this();
的構(gòu)造函數(shù)中的super();
后面。
super()
是調(diào)用父類構(gòu)造函數(shù),先有父親,再有兒子,所以在super();
之后。
this()
是調(diào)用自身構(gòu)造函數(shù),為了保證構(gòu)造代碼塊在類初始化時(shí)只執(zhí)行一次,所以只會插入到不含this();
的構(gòu)造函數(shù)中。
構(gòu)造代碼塊的作用:構(gòu)造函數(shù)的公共模塊。
示例代碼如下:
public class Animal {
public Animal() {
System.out.println("Animal 無參構(gòu)造函數(shù) end...");
}
}
public class Cat extends Animal {
private String name;
private int age;
{
System.out.println("Cat 構(gòu)造代碼塊 end...");
}
public Cat() {
System.out.println("Cat 無參構(gòu)造函數(shù) end...");
}
public Cat(String name) {
this.name = name;
System.out.println("Cat name參構(gòu)造函數(shù) end...");
}
public Cat(String name, int age) {
this();
this.name = name;
this.age = age;
System.out.println("Cat name age參構(gòu)造函數(shù) end...");
}
public static void main(String[] args) {
new Cat();
System.out.println("-----------------");
new Cat("dog");
System.out.println("-----------------");
new Cat("dog", 10);
}
}
打印結(jié)果:
image.png
打印結(jié)果很明顯,包含this()
的構(gòu)造函數(shù)中未執(zhí)行構(gòu)造代碼塊,并且構(gòu)造代碼塊在super()
之后執(zhí)行。
Cat 反編譯代碼后就一目了然,如下:
public class Cat extends Animal {
private String name;
private int age;
public Cat() {
System.out.println("Cat 構(gòu)造代碼塊 end...");
System.out.println("Cat 無參構(gòu)造函數(shù) end...");
}
public Cat(String name) {
System.out.println("Cat 構(gòu)造代碼塊 end...");
this.name = name;
System.out.println("Cat name參構(gòu)造函數(shù) end...");
}
public Cat(String name, int age) {
this();
this.name = name;
this.age = age;
System.out.println("Cat name age參構(gòu)造函數(shù) end...");
}
public static void main(String[] args) {
new Cat();
System.out.println("-----------------");
new Cat("dog");
System.out.println("-----------------");
new Cat("dog", 10);
}
public void run() {
System.out.println("cat run...");
}
}