Java執(zhí)行順序大揭秘:靜態(tài)塊、非靜態(tài)塊和構(gòu)造方法誰先誰后?
Hello大家好,我是小米!今天咱們來聊聊Java中的一個小而重要的知識點——初始化塊??赡苡械男』锇橐宦犨@名字就覺得有點頭大,這東西到底是干嘛的?為啥面試官總愛問它?別急,今天我會帶大家從原理到實戰(zhàn),一次性搞懂靜態(tài)初始化塊和非靜態(tài)初始化塊的執(zhí)行順序、優(yōu)先級和用法,讓面試官忍不住點頭!
什么是初始化塊?
在Java中,初始化塊(Initialization Block)是一段可以在類中定義的代碼,用于在創(chuàng)建對象時執(zhí)行某些特定的操作。根據(jù)是否帶有static關(guān)鍵字,可以分為:
- 靜態(tài)初始化塊(Static Initialization Block):用static關(guān)鍵字聲明,只會在類加載時執(zhí)行一次。
- 非靜態(tài)初始化塊(Instance Initialization Block):沒有static關(guān)鍵字,每次創(chuàng)建對象時都會執(zhí)行。
先別急著覺得難,初始化塊其實是Java中比較常見的用法,尤其是在需要初始化一些復(fù)雜的邏輯或共享資源時非常方便。我們從頭開始了解它們的執(zhí)行順序和用法!
靜態(tài)初始化塊:優(yōu)先級最高的初始化塊
1. 靜態(tài)初始化塊是什么?
靜態(tài)初始化塊,是由static關(guān)鍵字修飾的一段代碼。它的特性有:
- 只執(zhí)行一次:因為它是在類加載時執(zhí)行的,所以整個類生命周期中只會執(zhí)行一次。
- 優(yōu)先級最高:靜態(tài)初始化塊是類第一次加載時最先執(zhí)行的,甚至在main方法之前。
- 共享性強:由于它只執(zhí)行一次,所以適合用來初始化類級別的資源,比如靜態(tài)變量。
我們來看一個簡單的例子:
圖片
運行這段代碼,你會看到輸出結(jié)果為:
圖片
看到?jīng)]?靜態(tài)初始化塊在main方法之前執(zhí)行!這是因為Java在執(zhí)行代碼前,必須先加載類,而靜態(tài)初始化塊在類加載時就會執(zhí)行,這也就是為什么它的優(yōu)先級最高。
2. 靜態(tài)初始化塊的實際應(yīng)用場景
靜態(tài)初始化塊通常用于初始化一些需要在類加載時完成的邏輯,比如:
- 靜態(tài)變量的初始化:在塊中對靜態(tài)變量進行一些復(fù)雜的計算或邏輯操作。
- 初始化共享資源:比如數(shù)據(jù)庫連接池、文件資源等,這些資源只需要創(chuàng)建一次即可共享。
例如,假設(shè)我們有一個數(shù)據(jù)庫連接池:
圖片
在這個例子中,數(shù)據(jù)庫連接只需要創(chuàng)建一次,這樣可以確保每次調(diào)用getConnection時都能拿到已經(jīng)初始化好的連接。
非靜態(tài)初始化塊:每次創(chuàng)建對象時執(zhí)行
接下來我們說說非靜態(tài)初始化塊。它沒有static關(guān)鍵字,每次創(chuàng)建對象時都會被調(diào)用。非靜態(tài)初始化塊的執(zhí)行順序是在構(gòu)造方法之前,但在靜態(tài)初始化塊之后。
1. 非靜態(tài)初始化塊是什么?
非靜態(tài)初始化塊和靜態(tài)初始化塊的區(qū)別在于:
- 每次創(chuàng)建對象時都會執(zhí)行:只要你new一個對象,非靜態(tài)初始化塊就會執(zhí)行一次。
- 優(yōu)先級低于靜態(tài)初始化塊:靜態(tài)塊會最先執(zhí)行,接著才是非靜態(tài)塊。
來看下面的例子:
圖片
輸出結(jié)果為:
圖片
這里可以看到執(zhí)行順序是:
- 靜態(tài)初始化塊
- main方法開始
- 非靜態(tài)初始化塊
- 構(gòu)造方法
- main方法結(jié)束
2. 非靜態(tài)初始化塊的實際應(yīng)用場景
非靜態(tài)初始化塊通常用來初始化實例變量,或者是對對象進行一些準備操作。比如:
圖片
運行這段代碼會輸出:
圖片
每創(chuàng)建一個User對象,非靜態(tài)初始化塊都會執(zhí)行一次,用于初始化默認的age屬性,這樣每個對象的age值都默認是18。
總結(jié)一下執(zhí)行順序
到這里,我們對靜態(tài)初始化塊和非靜態(tài)初始化塊的執(zhí)行順序已經(jīng)有了清晰的了解,最終的執(zhí)行順序如下:
- 靜態(tài)初始化塊:在類加載時執(zhí)行,只執(zhí)行一次。
- 非靜態(tài)初始化塊:在對象創(chuàng)建時執(zhí)行,每次創(chuàng)建對象都會執(zhí)行。
- 構(gòu)造方法:緊隨非靜態(tài)初始化塊之后,構(gòu)造方法會執(zhí)行。
我們可以用這張圖來幫助記憶:
圖片
什么時候用靜態(tài)初始化塊和非靜態(tài)初始化塊?
靜態(tài)初始化塊
- 適用于需要類級別的初始化邏輯,比如初始化靜態(tài)變量、共享資源。
- 執(zhí)行一次的操作,可以放在靜態(tài)初始化塊中,確保不會重復(fù)執(zhí)行。
非靜態(tài)初始化塊
- 適用于對象級別的初始化邏輯,比如初始化實例變量。
- 每次創(chuàng)建對象都要執(zhí)行的操作,可以放在非靜態(tài)初始化塊中。