java類初始化的順序
先從最簡單的說起,我們一般是這樣理解的:
先初始化靜態 成員/塊 然後是構造程式碼塊,最後是建構函式 看一個例子
這是兩個類ShunXu 和 Other
public class ShunXu {
public ShunXu() {
System.out.println("建構函式");
}
public static Other other = new Other();
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
public static void main(String[] args) {
ShunXu shunXu = new ShunXu();
}
}
public class Other {
{
System.out.println("我是另一個類的構造程式碼快");
}
static {
System.out.println("我是另一個類的靜態塊");
}
}
首先明確一點,靜態程式碼塊和靜態成員變數是沒有先後之分,完全按照程式碼的順序執行
執行主函式,首先會裝載ShunXu->構造靜態成員變數other(other中先執行靜態塊,後執行構造程式碼塊)->執行靜態塊->構造程式碼塊->建構函式
因此,輸出結果就是
我是另一個類的靜態塊
我是另一個類的構造程式碼快
靜態塊
構造程式碼塊
建構函式
接下來看一個有些奇怪的例子
現在先不管Other,只關注ShunXu
public class ShunXu {
public ShunXu() {
System.out.println("建構函式");
}
static ShunXu shunXu = new ShunXu();
static ShunXu shunXu2 = new ShunXu();
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
public static void main(String[] args) {
}
}
我們在ShunXu內部建立了兩個靜態ShunXu物件
主函式本身什麼也不做,先看看輸出結果
構造程式碼塊
建構函式
構造程式碼塊
建構函式
靜態塊
是不是很神奇,靜態塊竟然最後執行
其實原因不難分析,可以看出建立兩個物件分別呼叫了兩次構造程式碼塊和建構函式,說明構造靜態物件的時候並沒有執行靜態塊,也就是說,靜態塊是由最外層的類來執行的。既然靜態塊寫在了靜態成員變數和後面,那麼它當然就得等靜態成員生成完再執行了
如果將靜態塊放在最前面
public class ShunXu {
public ShunXu() {
System.out.println("建構函式");
}
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
static ShunXu shunXu1 = new ShunXu();
static ShunXu shunXu2 = new ShunXu();
public static void main(String[] args) {
}
}
那麼輸出就是
靜態塊
構造程式碼塊
建構函式
構造程式碼塊
建構函式
這驗證我之前的說法:
靜態程式碼塊和靜態成員變數是沒有先後之分,完全按照程式碼的順序執行
那如果我們在主函式中再建立一個ShunXu物件呢
public class ShunXu {
public ShunXu() {
System.out.println("建構函式");
}
static ShunXu shunXu1 = new ShunXu();
static ShunXu shunXu2 = new ShunXu();
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
public static void main(String[] args) {
ShunXu xu = new ShunXu();
}
}
輸出為:
構造程式碼塊
建構函式
構造程式碼塊
建構函式
靜態塊
構造程式碼塊
建構函式
可以看出,這其實並沒有違背先靜態後非靜態的說法
剩下的就是關於父類的說明了
class Parent{
public Parent(){
System.out.println("父類構造方法");
}
static {
System.out.println("父類靜態塊");
}
}
public class ShunXu extends Parent{
public ShunXu() {
System.out.println("建構函式");
}
static ShunXu shunXu1 = new ShunXu();
static ShunXu shunXu2 = new ShunXu();
static {
System.out.println("靜態塊");
}
{
System.out.println("構造程式碼塊");
}
public static void main(String[] args) {
ShunXu xu = new ShunXu();
}
}
輸出結果為
1父類靜態塊
2父類構造方法
3構造程式碼塊
4建構函式
5父類構造方法
6構造程式碼塊
7建構函式
8靜態塊
9父類構造方法
10構造程式碼塊
11建構函式
輸出有些多,我們把它們給分割 1 - 7是兩個靜態成員的構造過程,先對載入其父類 然後呼叫父類構造方法 然後自身構造 8 - 11就是一個正常的物件的構造過程
說複雜的確有點,想通了其實問題就不大
相關文章
- Java子類和父類的初始化執行順序Java
- 淺談Java類中的變數初始化順序Java變數
- Java中class的初始化順序Java
- 九、 Java程式初始化的順序(二)Java
- 類的成員變數的初始化順序變數
- JVM類載入機制與類初始化順序JVM
- Java父子類載入順序Java
- 總結類初始化時的程式碼執行順序
- Java初始化靜態變數的時間順序Java變數
- Java中,類與類,類中的程式碼執行順序Java
- 程式碼說事 之 建立java物件的初始化順序Java物件
- java類內部程式碼執行順序Java
- static程式碼塊、構造程式碼塊、建構函式以及Java類初始化順序C程式函式Java
- Java static變數、作用域、建構函式初始化順序Java變數函式
- 類的例項化順序和分析
- DS順序表--類實現
- Java實現順序表Java
- C#類中方法的執行順序C#
- 學Java,Java書籍的最佳閱讀順序Java
- java運算子優先順序Java
- java基礎(四) java運算順序的深入解析Java
- Java中String類的初始化?Java
- 關於JAVA中順序IO的基本操作Java
- Java之執行緒的優先順序Java執行緒
- java setPriority()設定優先順序Java
- Java框架學習順序是哪些?Java框架
- Java框架學習順序是哪些Java框架
- C++ Qt開發:使用順序容器類C++QT
- 資料結構_順序表_順序表的初始化、插入、刪除、修改、查詢列印(基於C語言實現)資料結構C語言
- Java for迴圈中語句執行的順序Java
- 物件導向 -- 類的載入順序 類和物件的名稱空間物件
- Java流程控制02:順序結構Java
- 建立派生類物件,建構函式的執行順序物件函式
- python運算子及優先順序順序Python
- CSS 連結偽類選擇器順序原理CSS
- 順序表
- SuperObject Delphi 的 JSON 屬性亂序 – 操作類改造 – 關於屬性順序的問題ObjectJSON
- 第2章 順序表及其順序儲存