前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。
結論
??? 這里先把整理好的結論拋給大家,然后我在寫個程序來驗證我們的結論。在Java類被new的過程中,執行順序如下:
- ??? 實現自身的靜態屬性和靜態代碼塊。(根據代碼出現的順序決定誰先執行)
- ??? 實現自身的非靜態屬性和非靜態代碼塊。
- ??? 執行自身的構造函數。
??? 在實現繼承的類被new的過程中,初始化執行順序如下:
- ??? 實現父類的公共靜態屬性和靜態塊級代碼。
- ??? 實現自身的靜態屬性和靜態塊級代碼。
- ??? 實現父類的非靜態屬性和非靜態代碼塊。
- ??? 執行父類的構造函數。
- ??? 實現自身的非靜態屬性和非靜態代碼塊。
- ??? 執行自身的構造函數。
??? 這里需要簡單的介紹一下靜態代碼塊和非靜態代碼塊。
1. 靜態代碼塊:
??? static {??
??? }?
2. 非靜態代碼塊
??? {??
??? }?
??? 靜態代碼塊和非靜態代碼塊的異同點如下:
- ??? 相同點:都是JVM加載類時且在構造函數執行之前執行,在類中都可以定義多個,一般在代碼塊中對一些static變量進行賦值。
- ??? 不同點:靜態代碼塊在非靜態代碼塊之前執行(靜態代碼塊 > 非靜態代碼塊)。靜態代碼塊只在第一次new時執行一次,之后不再執行。而非靜態代碼塊每new一次就執行一次。
驗證
??? 對于結論的最好驗證就是寫出代碼來進行結果證明。首先,來看一下無繼承的類初始化時的執行順序,代碼如下:
?
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | public class InitOderTest { ?? public static String STATIC_FIELD = "靜態屬性" ; ??? ??? // 靜態塊 ?? static { ???? System.out.println(STATIC_FIELD); ???? System.out.println( "靜態代碼塊" ); ?? } ??? ??? public String field = "非靜態屬性" ; ??? ??? // 非靜態塊 ?? { ???? System.out.println(field); ???? System.out.println( "非靜態代碼塊" ); ?? } ? ??? public InitOderTest() { ???? System.out.println( "無參構造函數" ); ?? } ??? ??? public static void main(String[] args) { ???? InitOderTest test = new InitOderTest(); ?? } } |
??? 執行結果:
- ??? 靜態屬性?
- ??? 靜態代碼塊?
- ??? 非靜態屬性?
- ??? 非靜態代碼塊?
- ??? 無參構造函數?
??? 接下來,我們驗證一下,當Java類實現繼承后,執行順序是否和我們的結論吻合。測試代碼如下:
???
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | class ParentTest { ??? public static String PARENT_STATIC_FIELD = "父類-靜態屬性" ; ?? ???? // 父類-靜態塊 ??? static { ????? System.out.println(PARENT_STATIC_FIELD); ????? System.out.println( "父類-靜態代碼塊" ); ??? } ?? ???? public static String parentField = "父類-非靜態屬性" ; ?? ???? // 父類-非靜態塊 ??? { ????? System.out.println(parentField); ????? System.out.println( "父類-非靜態代碼塊" ); ??? } ?? ???? public ParentTest() { ????? System.out.println( "父類—無參構造函數" ); ??? } ? } ?? ?? public class InitOderTest extends ParentTest { ??? public static String STATIC_FIELD = "靜態屬性" ; ?? ???? // 靜態塊 ??? static { ????? System.out.println(STATIC_FIELD); ????? System.out.println( "靜態代碼塊" ); ??? } ?? ???? public String field = "非靜態屬性" ; ?? ???? // 非靜態塊 ??? { ????? System.out.println(field); ????? System.out.println( "非靜態代碼塊" ); ??? } ?? ???? public InitOderTest() { ????? System.out.println( "無參構造函數" ); ??? } ?? ???? public static void main(String[] args) { ????? InitOderTest test = new InitOderTest(); ??? } ? } |
??? 執行結果如下:
- ??? 父類-靜態屬性?
- ??? 父類-靜態代碼塊?
- ??? 靜態屬性?
- ??? 靜態代碼塊?
- ??? 父類-非靜態屬性?
- ??? 父類-非靜態代碼塊?
- ??? 父類—無參構造函數?
- ??? 非靜態屬性?
- ??? 非靜態代碼塊?
- ??? 無參構造函數