Java基礎總結 - 初始化塊

Java基礎總結 - 初始化塊
這篇文章只是把大學記的筆記整理到博客,方便自己查看,不保證權威性(•̀ᴗ•́)و ̑̑

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,滿足)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章