JAVA學習——靜態程式碼塊、構造程式碼塊、構造器、普通程式碼塊的執行順序
阿新 • • 發佈:2018-12-13
概念
在此之前,我們先來看看JAVA中的這些程式碼塊:
- 靜態程式碼塊
在類中使用static修飾,並使用"{}"括起來的程式碼片段。用於靜態變數的初始化或物件建立前的環境初始化。
- 構造程式碼塊
在類中沒與任何的字首或字尾,並使用"{}"括起來的程式碼片段。
- 普通程式碼塊
就是在方法後面使用"{}"括起來的程式碼片段,不能單獨執行,必須用其方法名呼叫才可以執行。
- 同步程式碼塊
使用synchronize關鍵字修飾,並使用"{}"括起來的程式碼片段。
表示在同一時間只能有一個執行緒進入到該方法塊中,是一種多執行緒保護機制。
例項
程式碼
public class Code { // 靜態程式碼塊 static{ System.out.println("我是靜態程式碼塊"); } {// 構造程式碼塊 System.out.println("我是構造程式碼塊"); } // 無參構造方法(構造器)(構造器的返回值型別就是類本身,無需寫) public Code() { System.out.println("我是無參構造方法"); } // 普通程式碼塊,必須要有返回值型別 public void Code1() { System.out.println("我是普通程式碼塊"); } public static void main(String[] args) { Code c1 = new Code(); Code c2 = new Code(); c1.Code1(); c2.Code1(); } }
結果
理解了上面的結果之後,問題來了,我們都知道程式碼塊沒有獨立執行的能力, 構造器(構造方法)是通過關鍵詞new來呼叫執行, 普通程式碼塊通過方法名呼叫執行, 那編譯器是如何處理構造程式碼塊的?
實際上,很簡單,編譯器會把構造程式碼塊插入到每個建構函式的最前端。相當於:
// 無參構造方法(構造器)(構造器返回值型別就是類本身,無需寫)
public Code() {
System.out.println("我是構造程式碼塊");
System.out.println("我是無參構造方法");
}
這樣,自然在通過new關鍵字生成一個例項的時侯會先執行構造程式碼塊,然後再執行其他程式碼(注意:構造程式碼塊不是在建構函式之前執行,而是依託於建構函式)
這就有了構造程式碼塊的兩個主要應用場景:
1. 初始化例項變數
如果每個建構函式都需要初始化變數,就可以通過構造程式碼塊來實現,從而取代在每個建構函式中都去呼叫初始化例項變數的方法。
2. 初始化例項環境
一個物件必須在適當的場景下才能存在,如果沒有適當的場景,則就需要在建立物件的時候建立此場景。如構造程式碼塊
這兩個場景就是利用了構造程式碼塊的兩個特性:
1. 在每個建構函式中都執行
2. 在建構函式中它會首先執行
構造程式碼塊的出現就是為了提取建構函式的共同量,降低各個建構函式的程式碼重複度。如下:
public class Code { public static int count = 0; { count++; } public Code() { } public Code(int i) { this(); } public Code(String string) { } public static void main(String[] args) { new Code(); new Code(1); new Code("1"); System.out.println(Code.count); } }
結果為3
拓展
對於有繼承的類來說,其中順序又是如何的呢?