做Java開發的,起碼要知道類的初始化順序,因為這樣你才知道編寫的代碼運作到了那裡。

一段代碼
public class BaseTest {
private String baseName = "baseName";
static {
System.out.println("父類靜态代碼塊");
}
public BaseTest() {
System.out.println("父類構造方法");
callName();
}
public void callName(){
System.out.println(baseName);
}
static class Sub extends BaseTest{
private String baseName = "subName";
public Sub() {
System.out.println("子類構造方法");
}
static {
System.out.println("子類靜态代碼塊");
}
@Override
public void callName() {
System.out.println(baseName); //輸出為null
super.callName(); //輸出baseName,baseStatic
}
}
public static void main(String[] args) {
Sub sub = new Sub();
}
}
以上代碼運作的結果如下:
父類靜态代碼塊
子類靜态代碼塊
父類構造方法
null
baseName
子類構造方法
為什麼在子類中直接調用 System.out.println(baseName),輸出為null呢?
在創造派生類的過程中首先建立基類對象,然後才能建立派生類。建立基類即預設調用BaseTest()方法,在方法中調用callName()方法,由于派生類中存在此方法,則被調用的callName()方法是派生類中的方法,此時派生類還未構造,是以變量baseName的值為null
靜态代碼塊的初始化
public class StaticTest {
static {
System.out.println("父類的靜态代碼塊");
}
public static String str = getStr();
private static String getStr() {
System.out.println("父類的靜态方法");
return "str1";
}
public StaticTest() {
System.out.println("父類構造方法");
}
static class SubStatic extends StaticTest{
static {
System.out.println("子類的靜态代碼塊");
}
public static String str1 = getStr1();
private static String getStr1() {
System.out.println("子類的靜态方法");
return "str1";
}
public SubStatic() {
System.out.println("子類構造方法");
}
}
public static void main(String[] args) {
new SubStatic();
}
}
運作結果:
父類的靜态代碼塊
父類的靜态方法
子類的靜态代碼塊
子類的靜态方法
父類構造方法
子類構造方法
最後
動手操作,檢視了下類的初始化過程。