類初始化 (static部分)
執行clinit方法
- main方法 所在的類需要 先加載和初始化
- 子類的初始化需要先初始化父類
- 類初始化就是指向<clinit>()方法
①、<clinit>()方法由靜態 類變量顯示賦值代碼 和 靜態代碼塊 組成
②、類變量顯示賦值代碼 和 靜態代碼塊代碼 從上到下 循序執行(<cliinit>()方法內順序執行)
③、<clinit>()方法 只執行一次
實例初始化 (非static部分)
實例初始化會執行<init>方法(上面是clinit即類的初始化)
- <init>()方法可能重載有多個,有幾個構造器就有幾個<init>方法
- <init>()方法由非靜態實例變量顯示賦值代碼塊和非靜態代碼塊、對應構造器代碼組成
- 非靜態實例變量顯示賦值代碼和非靜態代碼塊代碼從上到下順序執行,對應構造器代碼最後執行
- 每次創建實例對象,調用對應構造器,執行的就是對應的<init>()方法
- <init>()方法的首行是super()或super(實參參數列表)對應父類的<init>()方法
字節碼文件示例:
例題分析:
執行下面的Son類中的main方法會輸出什麼?
Father.java文件
public class Father{ private int i = test(); private static int j = method(); static{ System.out.print("(1)"); } Father(){ System.out.print("(2)"); } { System.out.print("(3)"); } public int test(){ System.out.print("(4)"); return 1; } public static int method(){ System.out.print("(5)"); return 1; } }
Son.java文件 執行下面的代碼會輸出什麼?
public class Son extends Father{ private int i = test(); private static int j = method(); static{ System.out.print("(6)"); } Son(){ // super();//寫或不寫都在,在子類構造器中一定會調用父類的構造器 System.out.print("(7)"); } { System.out.print("(8)"); } public int test(){ System.out.print("(9)"); return 1; } public static int method(){ System.out.print("(10)"); return 1; } public static void main(String[] args) { // Son s1 = new Son(); // System.out.println(); // Son s2 = new Son(); } }
結果