(1)靜態代碼塊、構造代碼塊的定義區別:
//靜態代碼塊 static{ System.out.println("靜態代碼塊"); } //構造代碼塊.使用{}聲明的代碼塊(和靜態代碼塊的區別是少了static關鍵字): { System.out.println("構造代碼塊"); }
(2)示例1:靜態代碼塊、構造代碼塊、構造函數、普通代碼塊的執行順序
public class CodeBlock { static{ System.out.println("靜態代碼塊"); } { System.out.println("構造代碼塊"); } public CodeBlock(){ System.out.println("無參構造函數"); } public void sayHello(){ { System.out.println("普通代碼塊"); } } public static void main(String[] args) { System.out.println("執行了main方法"); new CodeBlock().sayHello();; System.out.println("---------------"); new CodeBlock().sayHello();; } }
靜態代碼塊 執行了main方法 構造代碼塊 無參構造函數 普通代碼塊 --------------- 構造代碼塊 無參構造函數 普通代碼塊
解析:
-
靜態代碼塊最先執行,且先於static 的main方法執行
-
創建了兩個匿名對象,但是靜態代碼塊只是調用了一次。
-
每次創建對象的時候都會提前調用一次構造代碼塊
-
構造代碼塊在構造函數之前執行
(3)示例2:構造代碼塊、構造函數的執行順序
public class CodeBlock { public void sayHello(){ { System.out.println("普通代碼塊"); } } public CodeBlock(){ System.out.println("無參構造函數"); } { System.out.println("構造代碼塊"); } static{ System.out.println("靜態代碼塊"); } public static void main(String[] args) { System.out.println("執行了main方法"); new CodeBlock().sayHello();; System.out.println("---------------"); new CodeBlock().sayHello();; } }
靜態代碼塊 執行了main方法 構造代碼塊 無參構造函數 普通代碼塊 --------------- 構造代碼塊 無參構造函數 普通代碼塊
解析:驗證了構造代碼塊優先於構造函數執行,與定義順序無關
(4) 示例3::構造代碼塊的作用
public class Demo01 { public static void main(String[] args) { Test test = new Test(3); //構造代碼塊會在構造函數被調用時執行, 且在這個例子中比"this.id=id;"語句先執行,作用是給對象統一初始化數據; System.out.println(test); } } class Test{ int id; String name; { this.id= 5; System.out.println(this.id); this.name = "測試"; System.out.println("這是構造代碼塊"); } Test(int id){ this.id = id; } public String toString(){ return "name: "+this.name +","+"id: "+ this.id ;//這里的name沒有在構造函數中賦值,但是卻有值,因為構造代碼塊已經初始化過了 } }
5
這是構造代碼塊
name: 測試 , id: 3
如果把下面這一段注釋掉:name就沒有被初始化,只有默認值null
{ this.id= 5; System.out.println(this.id); //this.name = "測試"; System.out.println("這是構造代碼塊"); }
5 這是構造代碼塊 name: null,id: 3
解析:
-
構造代碼塊的作用是給構造函數初始化
-
構造代碼塊要優先於構造函數執行
(5)總結:
構造代碼塊、靜態代碼塊的定義不同
靜態代碼塊的作用是給類初始化
構造代碼塊的作用是給構造函數初始化