Java類的初始化順序 多說無益,以下是本人親自試驗的代碼,一目瞭然: 1 package test1; 2 3 public class Test { 4 public static void main(String[] argc) { 5 new Child(); 6 System.out.pr ...
Java類的初始化順序
多說無益,以下是本人親自試驗的代碼,一目瞭然:
1 package test1; 2 3 public class Test { 4 public static void main(String[] argc) { 5 new Child(); 6 System.out.println("================================"); 7 new Child(); 8 } 9 } 10 11 class Child extends Parent{ 12 private static String staticField = getStaticField(); 13 static { 14 System.out.println("child靜態方法塊初始化"); 15 } 16 private String field = getField(); 17 { 18 System.out.println("child普通方法塊初始化"); 19 } 20 21 public Child() { 22 System.out.println("child構造函數初始化"); 23 } 24 25 public static String getStaticField() { 26 System.out.println("child靜態屬性初始化"); 27 return "staticField"; 28 } 29 30 public static String getField() { 31 System.out.println("child普通屬性初始化"); 32 return "field"; 33 } 34 } 35 36 class Parent { 37 private static String staticField = getStaticField(); 38 static { 39 System.out.println("parent靜態方法塊初始化"); 40 } 41 private String field = getField(); 42 { 43 System.out.println("parent普通方法塊初始化"); 44 } 45 46 public Parent() { 47 System.out.println("parent構造函數初始化"); 48 } 49 50 public static String getStaticField() { 51 System.out.println("parent靜態屬性初始化"); 52 return "staticField"; 53 } 54 55 public static String getField() { 56 System.out.println("parent普通屬性初始化"); 57 return "field"; 58 } 59 }
列印結果:
1 parent靜態屬性初始化 2 parent靜態方法塊初始化 3 child靜態屬性初始化 4 child靜態方法塊初始化 5 parent普通屬性初始化 6 parent普通方法塊初始化 7 parent構造函數初始化 8 child普通屬性初始化 9 child普通方法塊初始化 10 child構造函數初始化 11 ================================ 12 parent普通屬性初始化 13 parent普通方法塊初始化 14 parent構造函數初始化 15 child普通屬性初始化 16 child普通方法塊初始化 17 child構造函數初始化
經過替換靜態屬性和靜態初始化塊的聲明順序發現靜態屬性和靜態初始化塊的初始化順序和聲明順序有關,同理,普通屬性和普通初始化塊的的初始化順序和聲明順序有關。
總結:
- 當某一個類滿足初始化的條件時(以後的博客中會有總結),先會初始化父類(從頂級父類Object依次向下初始化),然後初始化子類;
- 初始化該類時,最先初始化靜態屬性和靜態初始化塊(和聲明順序有關),從頂級父類Object依次向下初始化;
- 通過new創建對象時,先初始化普通屬性和普通初始化塊(和聲明順序有關),再調用構造方法,同樣從頂級父類Object依次向下執行;
- 靜態屬性和靜態初始化塊只會初始化一次,類初始化後,再次通過new創建對象,只會重覆執行第三步。
接下來引用Java編程思想的一句話:
在類的內部,變數定義的先後順序決定了初始化的順序,即使變數定義散佈於方法定義之間,它們仍舊會在任何方法(包括構造器)被調用之前得到初始化。
參考:Java編程思想中文版第四版第5章
及 https://www.cnblogs.com/fly-piglet/p/8766226.html