Java 中的靜態塊
Java 在物件初始化之前使用靜態塊來執行程式碼。當我們用 static
關鍵字宣告一個塊時,我們稱它為靜態塊。
它在 Java 中也稱為靜態初始化塊或靜態初始化塊。當類載入到記憶體中時,靜態塊體內的程式碼會執行一次。
語法:
static {
// body of the staic block
}
在 Java 中,靜態塊總是在 main
方法之前執行,因為它在類載入和物件建立之前儲存在記憶體中。
Java 中的靜態塊示例
讓我們通過這個例子來看看。在這裡,我們建立了一個靜態塊來檢查執行順序。
靜態塊首先執行,甚至在 main()
方法之前。
// Java Static Block Example
public class SimpleTesting {
// creating static block
static {
System.out.println("This is static block");
}
public static void main(String[] args) {
System.out.println("This is main method");
}
}
輸出:
This is static block
This is main method
這裡,JVM
首先執行靜態塊,在靜態塊完全執行之後,它執行 main()
方法。
這裡可能會出現一個問題:我們可以在不建立 main()
方法的情況下使用靜態塊嗎?答案是肯定的。
我們可以做 JDK version 1.6
或以前的版本;否則,它將在執行時顯示錯誤。
Java 6 中的靜態塊
在這裡,我們建立了一個靜態塊,並且該類不包含 main()
方法。此程式碼執行良好並顯示所需的結果。
public class SimpleTesting {
static {
System.out.println("This is static block");
}
}
輸出:
This is static block
Java 7 或更高版本中的靜態塊
如果我們在沒有 main()
方法的類中宣告靜態塊,則程式碼不會編譯並向控制檯丟擲錯誤。
public class SimpleTesting {
static {
System.out.println("This is static block");
}
}
輸出:
Error: Main method not found in class Example_1, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
讓我們再看一個靜態塊的例子。
在這裡,我們在另一個類中建立了一個靜態塊,並且在另一個類中宣告瞭 main()
方法。
使用類名訪問其變數時,程式碼執行得很好。請參見下面的示例。
class Sample {
static int a;
int b;
// creating the static block
static {
a = 20;
System.out.println("Static block");
}
}
public class SimpleTesting {
public static void main(String[] args) {
// accessing a without creating an object
System.out.println(Sample.a);
}
}
輸出:
Static block
20
Java 中的靜態塊和建構函式
請注意,靜態塊在建構函式之前執行。請參見下面的示例。
class Sample {
static int a;
int b;
// creating the static block
static {
a = 20;
System.out.println("I am static block");
}
// creating the constructor
Sample() {
System.out.println("I am constructor");
}
}
public class SimpleTesting {
public static void main(String[] args) {
// creating the objects
Sample obj1 = new Sample();
Sample obj2 = new Sample();
}
}
輸出:
I am static block
I am constructor
I am constructor
如果我們建立 5 個物件,那麼例項塊會執行 10 次,但靜態塊的執行並不依賴於物件的建立。
它的執行取決於類的載入,我們知道,類只載入一次,因此靜態塊只會執行一次。
public class SimpleTesting {
// Declaring two instance blocks.
{ System.out.println("This is instance block-1"); }
{ System.out.println("This instance block-2"); }
// Declaring two static blocks.
static {
System.out.println("Static block-1");
}
static {
System.out.println("Static block-2");
}
// Declaring zero parameter constructor.
SimpleTesting() {
System.out.println("0 argument constructor");
}
// Declaring one parameter constructor with int parameter named a.
SimpleTesting(int a) {
System.out.println("1 argument constructor");
}
public static void main(String[] args) {
// Creating an object of class.
new SimpleTesting(); // Nameless object.
// Creating another object of class and passing an integer argument value.
new SimpleTesting(20); // Nameless object.
}
}
輸出:
Static block-1
Static block-2
This is instance block-1
This instance block-2
0 argument constructor
This is instance block-1
This instance block-2
1 argument constructor
Java 中的多個靜態塊
Java 允許在一個類中建立任意數量的靜態塊。我們在一個類中建立了兩個靜態塊,程式碼執行得很好。
public class SimpleTesting {
static {
System.out.println("I am static block - 1");
}
static {
System.out.println("I am static block - 2");
}
public static void main(String[] args) {
System.out.println("I am main method");
}
}
輸出:
I am static block - 1
I am static block - 2
I am main method
在下面的例子中,我們在一個類中定義了一個 method
、constructor
、instant block
、static block
。
檢視執行順序以瞭解 JVM 執行優先順序
。
public class SimpleTesting {
int x = 10;
static int y = 20;
void fun1(int a) {
System.out.println("This is instance method");
}
static void fun2(String str) {
System.out.println("This is static method");
}
SimpleTesting() {
System.out.println("0 argument constructor");
}
SimpleTesting(int a) {
System.out.println("1 argument constructor");
}
{ System.out.println("This is instance block"); }
static {
System.out.println("This is static block");
}
public static void main(String[] args) {
SimpleTesting at = new SimpleTesting();
SimpleTesting at2 = new SimpleTesting(10);
at.fun1(50);
SimpleTesting.fun2("Name");
}
}
輸出:
This is static block
This is instance block
0 argument constructor
This is instance block
1 argument constructor
This is instance method
This is static method