欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中的靜態(tài)代碼塊與構(gòu)造代碼塊詳解

 更新時(shí)間:2024年11月04日 14:50:13   作者:薛定諤的鹽.  
靜態(tài)代碼塊在JVM加載類時(shí)執(zhí)行,僅執(zhí)行一次,用于初始化靜態(tài)變量或執(zhí)行一次性設(shè)置,構(gòu)造代碼塊在每次創(chuàng)建對(duì)象時(shí)執(zhí)行,用于實(shí)例變量的初始化或執(zhí)行創(chuàng)建對(duì)象時(shí)的公共邏輯,靜態(tài)代碼塊按定義順序執(zhí)行,構(gòu)造代碼塊在構(gòu)造方法前執(zhí)行

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ī)是在類加載過(guò)程中。類加載通常發(fā)生在以下情況之一時(shí):

  • 類的第一個(gè)實(shí)例被創(chuàng)建。
  • 訪問類的第一個(gè)靜態(tài)成員(靜態(tài)變量或靜態(tài)方法)。
  • 使用反射機(jī)制來(lái)加載類。

當(dāng)滿足上述任一條件時(shí),JVM會(huì)加載該類,并執(zhí)行類中的所有靜態(tài)代碼塊。

3. 作用

  • 初始化靜態(tài)變量:可以在靜態(tài)代碼塊中對(duì)靜態(tài)變量進(jìn)行復(fù)雜的初始化操作。
  • 執(zhí)行一次性設(shè)置:比如加載配置文件、初始化數(shù)據(jù)庫(kù)連接池等,僅需要在類加載時(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ì)象的過(guò)程中,會(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)造代碼塊適合用來(lái)進(jìn)行實(shí)例變量的復(fù)雜初始化操作,尤其是當(dāng)初始化邏輯需要在多個(gè)構(gòu)造方法中共享時(shí)。
  • 每次創(chuàng)建對(duì)象時(shí)執(zhí)行的邏輯:構(gòu)造代碼塊中的代碼每次創(chuàng)建對(duì)象時(shí)都會(huì)執(zhí)行,所以可以用來(lái)在對(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í)行。
  • 無(wú)論你調(diào)用哪個(gè)構(gòu)造方法,構(gòu)造代碼塊都將被執(zhí)行,從而確保一些邏輯可以在所有構(gòu)造方法執(zhí)行前運(yùn)行。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論