1.初始化塊
初始化塊,分爲一般初始化塊和靜態初始化塊,前者在創建對象時調用,後者在加載類時初始化靜態成員
(一般初始化塊也可以初始化靜態變量只是得在創建對象時候了,而靜態初始化不能初始化實例變量,因爲沒有this)
2.執行順序
父類靜態成員開闢空間->父類靜態初始化塊->子類靜態成員開闢空間->子類靜態初始化塊(即加載類的時候)
->父類實例全局變量->父類初始化塊->父類構造方法->子類實例全局變量->子類初始化塊->子類構造方法
3.初始化原理
變量初始化有三個過程,一個是定義時初始化,一個是初始化塊初始化,還有一個是構造方法初始化,
前兩個通過我反彙編,發現實際上前兩者會跟據出現順序加到構造方法上一起初始化,
所以一般初始化塊要寫在定義初始化(其實只是定義沒初始化的話影響並不大)後面,不然初始化塊初始化的值會被定義初始化的值覆蓋掉。
如下面代碼:name顯示按照初始化塊和定義初始化的順序,先被初始化爲"初始化塊初始化name",然後被初始化爲 "定義時初始化name",前兩者會根據
出現循序不同確定先執行那個,但最後都會執行構造方法的初始化,即賦值爲“構造器初始化”。public class BB{ public static void main(String[] agrs){ A a = new A(); } } class A{ { name = "初始化塊初始化name"; //System.out.println(name); 非法的向前引用 System.out.println(this.name); } String name = "定義時初始化name"; public A(){ System.out.println(name ); name = “構造器初始化” System.out.println(name ); } } //輸出結果: 初始化塊初始化name // 定義時初始化name // 構造器初始化
4.碰到的問題
初始化塊在屬性定義上面的時候能賦值 但不能輸出,一輸出就會出現非法的向前引用
但加上this之後就不會報錯 這讓我不理解,網上查到oracle官方的說明:
只有在全部滿足以下4點的情況下,成員變量的聲明才必須在使用之前,否則順序無關
•使用出現在C的實例/靜態變量初始化,或者C的實例/靜態初始化塊中 (System.out.println(name); 出現在非靜態初始化塊中,滿足)
•使用不在賦值表達式左邊 (輸出name,也即不在賦值表達式左邊,滿足)
•使用是通過簡單名稱 (name不帶類名,滿足)
•C是包含該使用的直接類/接口 (C即爲代碼中A,滿足)