Java基礎篇——靜態程式碼塊、靜態方法、靜態變數、構造方法、構造程式碼段相關
基本定義
- 靜態程式碼段
在Java類的設計中,如果某段程式碼想讓其只執行一次,比如一個HashMap的生成,一個數據庫連線池的產生,就可以把相關程式碼寫入static{}包裹的程式碼段中。這個程式碼段就叫靜態程式碼段,在專案啟動時就主動執行,即由虛擬機器內部完成呼叫,且只執行一次,適合做變數的初始化。
- 靜態變數
任何方法都不能宣告靜態變數,只能在類體中生成,可以由整個類進行呼叫,在類被呼叫時被賦值。
- 靜態方法
在類被載入時裝載,在類被呼叫時執行,且只能使用類中的其他靜態變數,內部不能存在任何形式的this和super呼叫,因為static方法無需例項化任何物件。
- 構造程式碼段
類載入時,即new ClassName()或Class.forName("ClassPath.ClassName.class")執行的程式碼。
- 構造方法(建構函式)
在類需要例項化時進行呼叫,執行順序滯後於構造程式碼段。
各段程式碼的執行順序
靜態程式碼段 >構造程式碼段>構造方法,如果有父類的話,先執行父類和子類的靜態程式碼段並將父類和子類的靜態變數進行裝載,然後執行父類的構造程式碼段和建構函式,再次是子類的構造程式碼段和建構函式,即,基類靜態程式碼段>子類靜態程式碼段>基類建構函式段>基類構造方法>子類構造程式碼段>子類構造方法。這裡用一個簡單的例子證明一下。
public class Base { private static int numOne; private int numTwo; static { System.out.println("基類靜態程式碼段的numOne:" + numOne); numOne = 10; } { System.out.println("基類構造程式碼段中的numOne:" + numOne + ", numTwo:" + numTwo); numTwo = 2; } public Base() { System.out.println("基類構造方法 numOne:" + numOne + ", numTwo:" + numTwo); numOne = 1; numTwo = 20; } protected void action() { System.out.println("被繼承方法"); doSome(); } protected void doSome() { System.out.println(numOne + " " + numTwo); } }
public class Son extends Base{ private static int num; private int anoNum; static { System.out.println("子類靜態程式碼段 num:" + num); num = 9; } { System.out.println("子類構造程式碼段 num:" + num + ", anoNum:" + anoNum); anoNum = 3; } public Son() { System.out.println("子類構造方法num:" + num + ", anoNum:" + anoNum); num = 30; anoNum = 90; } protected void doSome() { System.out.println(num + " " + anoNum); } }
public class Demo {
public static void main(String[] args) {
Son son1 = new Son();
Base base = son1;
Base anoBase = new Base();
son1.action();
base.action();
anoBase.action();
}
}
輸出:
基類靜態程式碼段的numOne:0
子類靜態程式碼段 num:0
基類構造程式碼段中的numOne:10, numTwo:0
基類構造方法 numOne:10, numTwo:2
子類構造程式碼段 num:9, anoNum:0
子類構造方法num:9, anoNum:3
基類構造程式碼段中的numOne:1, numTwo:0
基類構造方法 numOne:1, numTwo:2
被繼承方法
30 90
被繼承方法
30 90
被繼承方法
1 20
這裡三個action執行過程是,son1.action本應通過物件son1查詢到Son類的action方法並執行,發現不存在後,追溯至父類,找到後執行。對於base,執行如上操作,存在,通過類Son呼叫,不存在,則繼續追溯。由於base變數的值與c的值一致,即都指向同一段Son空間,所以和son1的執行結果一致。對於anoBase,先查詢類Base中是否存在action,發現存在後執行該方法,得到結果,1,20。
總結
靜態塊程式碼作用於類級別,類載入時被裝載,且只被載入一次,用於進行屬性的初始化,而構造方法和構造程式碼段作用於物件級別,當物件需要例項化時才被呼叫。構造程式碼段在每例項化一個物件時進行一次呼叫,並優先於建構函式,用於初始化例項環境和不同物件共性的例項化內容。建構函式每例項化一個物件時都會執行一次,用以初始化物件屬性。