java 程式碼塊(區域性程式碼塊、例項程式碼塊、靜態程式碼塊、同步程式碼塊)
阿新 • • 發佈:2022-01-06
1 引言
程式碼塊是類的成分之一:成員變數,方法,構造器,程式碼塊,內部類。
在Java中,使用 { } 括起來的程式碼被稱為程式碼塊(Code block)
1.1 程式碼塊的分類
根據其位置和宣告的不同,可以分為:
- 區域性程式碼塊:用於限定變數生命週期,及早釋放,提高記憶體利用率。
- 靜態程式碼塊:主要用於對靜態屬性進行初始化。
- 例項(構造)程式碼塊:呼叫構造方法都會執行,並且在構造方法前執行。
- 同步程式碼塊:一種多執行緒保護機制。
2 區域性程式碼塊
在方法中出現,可以限定變數生命週期,及早釋放,提高記憶體利用率。
2.1 示例程式碼
public class Test1{ public static void main(String[] args) { //區域性程式碼塊 { int n = 100; } // 區域性程式碼塊中宣告的變數在程式碼塊外部訪問不到! // System.out.println(n); } }
3 靜態程式碼塊
必須有static修飾,必須放在類下。與類一起載入執行。並且靜態程式碼塊執行一次
3.1 示例程式碼
public class Test2 { public static String name; // 靜態程式碼塊 static { // 初始化靜態資源 name = "張三"; System.out.println("靜態程式碼塊執行..."); } public static void main(String[] args) { System.out.println("main方法執行..."); System.out.println(name); } }
輸出
靜態程式碼塊執行...
main方法執行...
張三
3.2 特點
- 每次執行類,載入類的時候都會先執行靜態程式碼塊一次。
- 靜態程式碼塊是自動觸發執行的,只要程式啟動靜態程式碼塊就會先執行一次。
- 在啟動程式之前可以做資源的初始化,一般用於初始化靜態資源。
4 例項程式碼塊(構造程式碼塊)
沒有static修飾,必須放在類下。與物件初始化一起載入,即每次呼叫構造方法都會執行,並且在構造方法前執行。
4.1 示例程式碼
public class Test3{ private String name; // 例項程式碼塊。 無static修飾。 { System.out.println("例項程式碼塊執行..."); name = "張三"; } // 構造器 public Test3(){ System.out.println("無參構造方法執行..."); } // 有引數構造器 public Test3(String name){ System.out.println("有參構造方法執行..."); this.name = name; } public static void main(String[] args) { Test3 t1 = new Test3(); Test3 t2 = new Test3("李四"); System.out.println(t1.name + t2.name); } }
輸出
例項程式碼塊執行...
無參構造方法執行...
例項程式碼塊執行...
有參構造方法執行...
張三李四
4.2 特點
- 無static修飾。屬於物件,與物件的建立一起執行的。
- 每次呼叫構造器初始化物件,例項程式碼塊都要自動觸發執行一次。
- 例項程式碼塊實際上是提取到每一個構造器中去執行的。
- 例項程式碼塊中的內容在構造方法前執行。
4.3 靜態程式碼塊、構造程式碼塊、建構函式執行順序
父類靜態程式碼塊 > 子類靜態程式碼塊 > main()方法 > 父類程式碼塊 > 父類構造器 > 子類程式碼塊 > 子類構造器
5 同步程式碼塊
同步程式碼塊指的是被Java中Synchronized關鍵詞修飾的程式碼塊,在Java中,Synchronized關鍵詞不僅僅可以用來修飾程式碼塊,與此同時也可以用來修飾方法,是一種執行緒同步機制,被Synchronized關鍵詞修飾的程式碼塊會被加上內建鎖。
5.1 程式碼示例
public class Test4 implements Runnable {
@Override
public void run() {
synchronized (CodeBlock.class) {
System.out.print("同步程式碼塊...");
}
}
public static void main(String[] args) {
CodeBlock a = new CodeBlock();
CodeBlock b = new CodeBlock();
new Thread(a).start();
new Thread(b).start();
}
}