網頁

2019/4/5

Java static block與non-static block的差別

Java類別中,可使用靜態區塊(static block)及非靜態區塊(non-static block)來進行類別建構實例前的一些初始化動作,其區別如下。

首先看看什麼是static block和non-static block,例如下面的MyClass中定義了static block及non-static block及其建構式。

public class MyClass {

    static {
        System.out.println("靜態區塊 static block...");
    }

    {
        System.out.println("非靜態區塊 non-static block...");
    }

    public MyClass() {
        System.out.println("建構式 constructor");
    }

}

所以static block與non-static block的第一個區別是,static block前會加上static關鍵字,但non-static block並沒有。


接著看以下範例。下面Main程式中有兩個類別ChildParent,且Child繼承Parent

public class Main {

    public static void main(String[] args) {
        new Child();
        System.out.println("------------------------");
        new Child();
        
    }

}

class Parent {
    
    private static Foo foo = new Foo("Parent");

    static {
        System.out.println("Parent static block...");
    }

    {
        System.out.println("Parent non-static block...");
    }

    public Parent() {
        System.out.println("Parent()...");
    }

}

class Child extends Parent {

    private static Foo foo = new Foo("Child");
    
    static {
        System.out.println("Child static block...");
    }

    {
        System.out.println("Child non-static block...");
    }

    public Child() {
        System.out.println("Child()...");
    }

}

class Foo {
    
   public Foo (String s) {
       System.out.println("Foo()..." + "called in " + s);
   }
}

main()方法中建構了兩次Child,執行結果如下:

Foo()...called in Parent
Parent static block...
Foo()...called in Child
Child static block...
Parent non-static block...
Parent()...
Child non-static block...
Child()...
------------------------
Parent non-static block...
Parent()...
Child non-static block...
Child()...

從以上的執行順序可以看到:

  • 類別的靜態成員變數及static block最先執行,依出現的順序執行,僅被執行一次。
  • 雖然建構了兩次Child,但其static block只會被執行一次。
  • 父類Parent的static block會先被執行,且也只被執行一次。
  • 每一次建構實例時,non-static block都會被執行,且順序先於建構式。
  • 每一次建構實例時,父類Parent的non-static block先會被執行,然後是父類的建構式,接著才是子類Child的non-static block,最後才是子類的建構式。

所以static block與non-static block的區別為:

  • static block前有static關鍵字,但non-static block沒有。
  • static block不論建構了多少實例,只會在第一次建構前執行一次,non-static block則是每次建構都被執行。
  • static block的順序先於non-static block。
  • static block是在JVM的class loader載入該類別時被執行,non-static block是在建構實例時被執行。
  • static block僅能存取靜態成員變數及方法,無法存取非靜態成員變數及方法,non-static block可以存取靜態及非靜態的成員變數及方法。

參考:

2 則留言:

  1. [類別的靜態成員變數會先被執行,順序先於static block,僅被執行一次]

    這個是因為上述程式碼static member先寫,若把static block寫在前頭,則static block將會先被執行!

    回覆刪除
  2. @樓上,感謝您的糾正,static block與static member variable的執行順序會依出現的順序來執行,文章已修正,謝謝。

    回覆刪除