class Parent { // 静态变量 public static String p_StaticField = "父类--静态变量"; // 变量(其实这用对象更好能体同这一点,如专门写一个类的实例) //如果这个变量放在初始化块的后面,是会报错的,因为你根本没有被初始化 public String p_Field = "父类--变量"; // 静态初始化块 static { System.out.println(p_StaticField); System.out.println("父类--静态初始化块"); } // 初始化块 { System.out.println(p_Field); System.out.println("父类--初始化块"); } // 构造器 public Parent() { System.out.println("父类--构造器"); } } public class SubClass extends Parent { // 静态变量 public static String s_StaticField = "子类--静态变量"; // 变量 public String s_Field = "子类--变量"; // 静态初始化块 static { System.out.println(s_StaticField); System.out.println("子类--静态初始化块"); } // 初始化块 { System.out.println(s_Field); System.out.println("子类--初始化块"); } // 构造器 public SubClass() { //super(); System.out.println("子类--构造器"); } // 程序入口 public static void main(String[] args) { System.out.println("*************in main***************"); new SubClass(); System.out.println("*************second subClass***************"); new SubClass(); } }
輸出結果
父類別--靜態變數
父類別--靜態初始化區塊
子類別--靜態變數
子類別--靜態初始化區塊
*************in main***************
父類別--變數
父類別--初始化區塊
父類別--建構器
子類別--變數
子類別--初始化區塊
子類別--建構器
*************second subClass***************
父類別--變數
父類別--初始化區塊
父類別--建構器
子類別--變數
子類別--初始化區塊
子類別--建構器
結果分析:
很明顯在載入main方法後,靜態變數不管父類別還是子類別的都執行了,然後才是父類別和子類別的普通變數和建構器的。這是因為,當要建立子類別這個物件時,發現這個類別需要一個父類,所以把父類的.class載入進來,然後依序初始化其普通變數和初始化程式碼區塊,最後其建構器,然後可以開始子類別的工作,把子類別的.class載入進來,在做子類別的工作。
另外在Java中子類別中都會有預設的呼叫父類別的預設建構函式即super(),當僅僅有預設建構函式裡
Java替你做了,我們可以做個實驗,如果在父類別中註解掉預設建構函數,加上一個有參的建構子時,如果
子類別中不加super(argument),此時會報語法錯誤
如果我們把Main方法中的內容全註解掉,你會發現只會輸出
父類--靜態變數
父類--靜態初始化區塊
子類別--靜態原因呢? 還要研究