[英]static keyword in Java
class A {
static {
System.out.println("A-SIB");
}
static void test(){
System.out.println("A-test");
}
}
class B extends A {
static {
System.out.println("B-SIB");
}
}
class C {
public static void main(String args []){
B.test();
}
}
當我運行C級時,我認為將打印A-SIB
, B-SIB
和A-test
,但輸出中沒有B-SIB
。 有人可以解釋一下原因嗎?
以下是JLS關於類初始化的說法:
類的初始化包括執行其靜態初始化程序和類中聲明的靜態字段(類變量)的初始化程序。
接口的初始化包括執行接口中聲明的字段(常量)的初始化器。
在初始化類之前,必須初始化其直接超類,但不會初始化類實現的接口。 同樣,在初始化接口之前,不會初始化接口的超接口。
類或接口類型T將在第一次出現以下任何一個之前立即初始化:
- T是一個類,並且創建了T的實例。
- T是一個類,並且調用由T聲明的靜態方法。
- 分配由T聲明的靜態字段。
- 使用由T聲明的靜態字段,該字段不是常量變量(第4.12.4節)。
- T是頂級類(第7.6節),並且執行在詞典內嵌套在T(第8.1.3節)內的斷言語句(第14.10節)。
對靜態字段(第8.3.1.1節)的引用僅導致實際聲明它的類或接口的初始化,即使它可能通過子類的名稱,子接口或實現接口的類來引用。
在這種情況下,使用B類在C中執行的所有操作都是調用靜態方法test()
。 但是此方法在A中聲明,而不是在B中聲明。因此,JVM不初始化類B,因此不會調用其靜態初始化程序塊。
請注意,B類在C的字節碼中引用,並由JVM加載。 但它沒有初始化。 如果刪除B.class
並嘗試運行C,則會出現異常。
Class B
沒有實現(也就是“隱藏”) static test
方法,因此初始執行在Class A
(因此是A-SIB)內開始; 然后用A
的test
方法(因此“A-測試”)。 如果您在Class B
覆蓋test
,您將獲得A-SIB B-SIB B測試
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.