Java中的靜態(tài)代碼塊與構(gòu)造代碼塊詳解
1、靜態(tài)代碼塊
1. 底層原理
靜態(tài)代碼塊在類的字節(jié)碼被加載到JVM時(shí)執(zhí)行,并且在整個(gè)JVM生命周期中只會(huì)執(zhí)行一次。
JVM在加載類時(shí),先加載類的字節(jié)碼,接著在類中查找靜態(tài)成員和靜態(tài)代碼塊。
所有的靜態(tài)代碼塊會(huì)按照它們?cè)陬愔卸x的順序依次執(zhí)行。
2. 執(zhí)行時(shí)機(jī)
靜態(tài)代碼塊的執(zhí)行時(shí)機(jī)是在類加載過程中。類加載通常發(fā)生在以下情況之一時(shí):
- 類的第一個(gè)實(shí)例被創(chuàng)建。
- 訪問類的第一個(gè)靜態(tài)成員(靜態(tài)變量或靜態(tài)方法)。
- 使用反射機(jī)制來加載類。
當(dāng)滿足上述任一條件時(shí),JVM會(huì)加載該類,并執(zhí)行類中的所有靜態(tài)代碼塊。
3. 作用
- 初始化靜態(tài)變量:可以在靜態(tài)代碼塊中對(duì)靜態(tài)變量進(jìn)行復(fù)雜的初始化操作。
- 執(zhí)行一次性設(shè)置:比如加載配置文件、初始化數(shù)據(jù)庫連接池等,僅需要在類加載時(shí)執(zhí)行一次的操作。
- 用于捕捉類的加載時(shí)間點(diǎn):有時(shí)我們希望在類加載時(shí)執(zhí)行某些邏輯,靜態(tài)代碼塊是一個(gè)非常合適的地方。
4. 示例
public class StaticBlock {
static {
System.out.println("靜態(tài)代碼塊 1 被執(zhí)行。");
}
static int staticVar = initStaticVar();
static {
System.out.println("靜態(tài)代碼塊 2 被執(zhí)行。");
}
private static int initStaticVar() {
System.out.println("靜態(tài)變量被初始化。");
return 1024;
}
public static void main(String[] args) {
System.out.println("主方法被執(zhí)行。");
System.out.println("靜態(tài)變量staticVar的值為: " + staticVar);
}
}運(yùn)行結(jié)果為:
靜態(tài)代碼塊 1 被執(zhí)行。
靜態(tài)變量被初始化。
靜態(tài)代碼塊 2 被執(zhí)行。
主方法被執(zhí)行。
靜態(tài)變量staticVar的值為: 1024
在這個(gè)示例中:
- 靜態(tài)代碼塊按照它們?cè)陬愔卸x的順序執(zhí)行。
- 靜態(tài)變量
staticVar的初始化發(fā)生在第一個(gè)靜態(tài)代碼塊和第二個(gè)靜態(tài)代碼塊之間。 - 這些操作只在類首次加載時(shí)執(zhí)行一次。
2、構(gòu)造代碼塊
1. 底層原理
構(gòu)造代碼塊是在每次創(chuàng)建對(duì)象時(shí)執(zhí)行的。JVM在構(gòu)造對(duì)象的過程中,會(huì)在調(diào)用構(gòu)造方法之前執(zhí)行構(gòu)造代碼塊。
構(gòu)造代碼塊可以用于在對(duì)象創(chuàng)建時(shí)對(duì)實(shí)例變量進(jìn)行初始化,或者執(zhí)行一些在每次創(chuàng)建對(duì)象時(shí)需要執(zhí)行的代碼。
2. 執(zhí)行時(shí)機(jī)
每次創(chuàng)建對(duì)象時(shí),JVM首先會(huì)在堆內(nèi)存中分配對(duì)象的內(nèi)存,然后按照以下步驟執(zhí)行:
- 初始化實(shí)例變量為默認(rèn)值。
- 執(zhí)行構(gòu)造代碼塊,按它們?cè)陬愔卸x的順序執(zhí)行。
- 執(zhí)行構(gòu)造方法。
因此,構(gòu)造代碼塊的執(zhí)行是在構(gòu)造方法之前的,即使在構(gòu)造方法中進(jìn)行實(shí)例變量的賦值,構(gòu)造代碼塊中的代碼也會(huì)先于這些操作執(zhí)行。
3. 作用
- 實(shí)例變量的復(fù)雜初始化:構(gòu)造代碼塊適合用來進(jìn)行實(shí)例變量的復(fù)雜初始化操作,尤其是當(dāng)初始化邏輯需要在多個(gè)構(gòu)造方法中共享時(shí)。
- 每次創(chuàng)建對(duì)象時(shí)執(zhí)行的邏輯:構(gòu)造代碼塊中的代碼每次創(chuàng)建對(duì)象時(shí)都會(huì)執(zhí)行,所以可以用來在對(duì)象創(chuàng)建時(shí)執(zhí)行一些公共的邏輯。
4. 示例
public class ConstructBlock {
{
System.out.println("構(gòu)造代碼塊 1 被執(zhí)行。");
}
int constructVar = initConstructVar();
{
System.out.println("構(gòu)造代碼塊 2 被執(zhí)行。");
}
private int initConstructVar() {
System.out.println("成員變量被初始化。");
return 1024;
}
public ConstructBlock() {
System.out.println("構(gòu)造方法被執(zhí)行。");
}
public static void main(String[] args) {
System.out.println("創(chuàng)建第一個(gè)對(duì)象:");
new ConstructBlock();
System.out.println("\n創(chuàng)建第二個(gè)對(duì)象:");
new ConstructBlock();
}
}運(yùn)行結(jié)果為:
創(chuàng)建第一個(gè)對(duì)象:
構(gòu)造代碼塊 1 被執(zhí)行。
成員變量被初始化。
構(gòu)造代碼塊 2 被執(zhí)行。
構(gòu)造方法被執(zhí)行。創(chuàng)建第二個(gè)對(duì)象:
構(gòu)造代碼塊 1 被執(zhí)行。
成員變量被初始化。
構(gòu)造代碼塊 2 被執(zhí)行。
構(gòu)造方法被執(zhí)行。
在這個(gè)示例中:
- 每次創(chuàng)建對(duì)象時(shí),構(gòu)造代碼塊和實(shí)例變量的初始化邏輯都會(huì)執(zhí)行。
- 無論你調(diào)用哪個(gè)構(gòu)造方法,構(gòu)造代碼塊都將被執(zhí)行,從而確保一些邏輯可以在所有構(gòu)造方法執(zhí)行前運(yùn)行。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Mybatis-Plus自動(dòng)生成id涉及的問題解決過程
文章主要講述了解決用戶ID在頁面和數(shù)據(jù)庫中不一致的問題,并提供了兩種解決方案:將主鍵類型改為String或刪除數(shù)據(jù)庫表重新創(chuàng)建以清空最大id2025-12-12
Spring動(dòng)態(tài)修改bean屬性配置key的幾種方法
在Spring應(yīng)用開發(fā)中,我們經(jīng)常需要從配置文件讀取屬性值并注入到bean中,但是你有沒有遇到過這種情況:某個(gè)bean的屬性需要根據(jù)運(yùn)行環(huán)境動(dòng)態(tài)切換配置key? 比如測(cè)試環(huán)境和生產(chǎn)環(huán)境使用不同的數(shù)據(jù)庫配置前綴?今天我們就來探討這個(gè)看似簡(jiǎn)單卻經(jīng)常讓人頭疼的問題2025-04-04
圖解Java經(jīng)典算法折半查找的原理與實(shí)現(xiàn)
折半查找法也叫做?分查找,顧名思義就是把數(shù)據(jù)分成兩半,再判斷所查找的key在哪?半中,再重復(fù)上述步驟知道找到?標(biāo)key,下面這篇文章主要介紹了圖解Java經(jīng)典算法折半查找的原理與實(shí)現(xiàn)2022-09-09
java數(shù)組及arrays類對(duì)數(shù)組的操作實(shí)例
下面小編就為大家?guī)硪黄猨ava數(shù)組及arrays類對(duì)數(shù)組的操作實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10
SpringBoot使用Redisson時(shí)候進(jìn)行Redis事務(wù)回滾方式
這篇文章主要介紹了SpringBoot使用Redisson時(shí)候進(jìn)行Redis事務(wù)回滾方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-05-05
Intellij Idea 多模塊Maven工程中模塊之間無法相互引用問題
這篇文章主要介紹了Intellij Idea 多模塊Maven工程中模塊之間無法相互引用問題,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

