Java實例初始化程序塊

實例初始化程序塊用於初始化實例數據成員。 它在每次創建類的對象時運行。實例變量的初始化可以是直接的,但是可以在初始化實例初始化塊中的實例變量時執行額外的操作。

什麼是實例初始化塊的使用,我們可以直接分配一個值在實例數據成員? 例如:

class Bike{  
    int speed=100;  
}

爲什麼要使用實例初始化塊?

假設在賦值給實例數據成員時必須要執行一些操作。 如:使用for循環來填充複雜數組或錯誤處理等。

實例初始化程序塊的示例

下面來看看實例初始化塊執行初始化的簡單例子。

class Bike7 {
    int speed;

    Bike7() {
        System.out.println("speed is " + speed);
    }

    {
        speed = 100;
    }

    public static void main(String args[]) {
        Bike7 b1 = new Bike7();
        Bike7 b2 = new Bike7();
    }
}

執行上面代碼得到以下結果 -

speed is 100
speed is 100

在Java中有三個地方可以執行實例初始化塊操作:

  1. 方法
  2. 構造函數
  3. 代碼塊

實例初始化塊或構造函數哪個先調用?

看看下面代碼就知道了。

class Bike8 {
    int speed;

    Bike8() {
        System.out.println("constructor is invoked");
    }

    {
        System.out.println("instance initializer block invoked");
    }

    public static void main(String args[]) {
        Bike8 b1 = new Bike8();
        Bike8 b2 = new Bike8();
    }
}

執行上面代碼得到以下結果 -

instance initializer block invoked
constructor is invoked
instance initializer block invoked
constructor is invoked

在上面的例子中,似乎首先調用實例初始化塊,但是可惜不是。 實例初始化塊在對象創建時被調用。 java編譯器在第一個語句super()之後的構造函數中複製實例初始化塊。 首先,調用構造函數。 讓我們通過下面的圖來理解它:

注意:java編譯器在每個構造函數中會自動複製實例初始化塊的代碼。

Java實例初始化程序塊

實例初始化塊的規則:

實例初始化塊主要有三個規則。 它們如下:

  1. 在創建類的實例時創建實例初始化程序塊。
  2. 在父類構造函數被調用之後(即在super()構造函數調用之後)調用實例初始化塊。
  3. 實例初始化程序塊按它們顯示的順序排列。

super()之後調用的實例初始化塊的程序示例:

class A {
    A() {
        System.out.println("parent class constructor invoked");
    }
}

class B2 extends A {
    B2() {
        super();
        System.out.println("child class constructor invoked");
    }

    {
        System.out.println("instance initializer block is invoked");
    }

    public static void main(String args[]) {
        B2 b = new B2();
    }
}

上面代碼執行結果如下 -

parent class constructor invoked
instance initializer block is invoked
child class constructor invoked

實例塊的另一個示例

class A {
    A() {
        System.out.println("parent class constructor invoked");
    }
}

class B3 extends A {
    B3() {
        super();
        System.out.println("child class constructor invoked");
    }

    B3(int a) {
        super();
        System.out.println("child class constructor invoked " + a);
    }

    {
        System.out.println("instance initializer block is invoked");
    }

    public static void main(String args[]) {
        B3 b1 = new B3();
        B3 b2 = new B3(10);
    }
}

上面代碼執行結果如下 -

parent class constructor invoked
instance initializer block is invoked
child class constructor invoked
parent class constructor invoked
instance initializer block is invoked
child class constructor invoked 10