前言
今天在看Android ContentProvider實現的時候,突然想到了Java類在new的過程中,靜態域、靜態塊、非靜態域、非靜態塊、構造函數的執行順序問題。其實這是一個很經典的問題,非常考察對Java基礎知識的掌握程度。很多面試過程中相信也有這樣的問題,趁著周末有時間復習一下。
結論
這里先把整理好的結論拋給大家,然后我在寫個程序來驗證我們的結論。在Java類被new的過程中,執行順序如下:
在實現繼承的類被new的過程中,初始化執行順序如下:
這里需要簡單的介紹一下靜態代碼塊和非靜態代碼塊。
1. 靜態代碼塊:
static {
}
2. 非靜態代碼塊
{
}
靜態代碼塊和非靜態代碼塊的異同點如下:
驗證
對于結論的最好驗證就是寫出代碼來進行結果證明。首先,來看一下無繼承的類初始化時的執行順序,代碼如下:
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類實現繼承后,執行順序是否和我們的結論吻合。測試代碼如下:
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(); } }
執行結果如下:
新聞熱點
疑難解答