1、在任何事情發生之前,將分配給對象的存儲空間初始化為0;
2、從根基類開始遞歸,按照類中的聲明順序調用靜態代碼塊、靜態成員的初始化方法。
但是有兩個例外:
- 定義為final非靜態基本數據類型的成員變量此時也會被初始化;
- 有且只有定義為final非靜態的String成員變量,采用的“=”賦值初始化會被執行(非new)。我們知道java中沒有
操作符重載這一概念,能通過“=”直接賦值的類只有String或Integer等java內部實現的final類。奇怪的是這里只有String能夠初始化,
Integer等不行,具體只能看java虛擬機的實現了
3、從根基類開始,按照類中的聲明順序調用非靜態代碼塊和非靜態成員(除了2中的幾個final特例)初始化方法,再調用構造函數,然后向子類遞歸初始化;
注意:在父類構造函數內部調用具有多態行為的函數將導致無法預測的結果,因為此時會調用子類override后的方法,而此時所有子類的
非靜態成員可能還沒有初始化,不會得到我們想要的結果。
測試平台:win10(32) + jre1.8.0_73 + eclipse
測試代碼:
基類
public class BaseInit {
static {
System.out.println("<<<基類靜態代碼塊>>>");
}
public BaseInit() {
System.out.println("<<<基類構造函數>>>");
//調用子類的override函數,訪問子類未初始化的非靜態成員變量
dangerTest();
}
{
System.out.println("<<<基類非靜態代碼塊>>>");
}
//need override
public void dangerTest() { }
}
子類:
public class DeriveInit extends BaseInit {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new DeriveInit();
}
/**
* 構造函數
*/
public DeriveInit() {
System.out.println("<<<子類構造函數>>>");
if(testNonStatic == 555)
{
System.out.println("成員變量已經初始化");
}
}
/**
* 靜態
*/
static private int testStatic = 100;
static {
System.out.println("<<<子類靜態代碼塊>>>");
if(testStatic == 100)
{
System.out.println("同一類內靜態按照聲明順序初始化");
}
}
/**
* 非靜態
*/
private int testNonStatic = 555;
{
System.out.println("<<<子類非靜態代碼塊>>>");
if(testNonStatic == 555)
{
System.out.println("同一類內非靜態按照聲明順序初始化");
}
}
/**
* 在基類中訪問子類的非靜態成員變量
*/
private int derive0 = 888;
final private int derive1 = 888;
final private Integer derive2 = 888;
final private String derive3 = new String("Hello World");
final private String derive4 = "Hello World";@Override
public void dangerTest()
{
System.out.println("子類成員變量derive0 = " + derive0);
System.out.println("子類成員變量derive1 = " + derive1);
System.out.println("子類成員變量derive2 = " + derive2);
System.out.println("子類成員變量derive3 = " + derive3);
System.out.println("子類成員變量derive4 = " + derive4);
}
}
運行結果:
<<<基類靜態代碼塊>>>
<<<子類靜態代碼塊>>>
同一類內靜態代碼按照聲明順序初始化
<<<基類非靜態代碼塊>>>
<<<基類構造函數>>>
子類成員變量derive0 = 0
子類成員變量derive1 = 888
子類成員變量derive2 = null
子類成員變量derive3 = null
子類成員變量derive4 = Hello World
<<<子類非靜態代碼塊>>>
同一類內非靜態代碼按照聲明順序初始化
<<<子類構造函數>>>
成員變量已經初始化
--僅供參考,歡迎交流--
