簡體   English   中英

java繼承的靜態初始化

[英]java static initialization with inheritance

public class Main {

    public static void main(String[] args) {
        System.out.println(B.x);
    }

}
class A {
    public static String x = "x";
}
class B extends A {
    static {
        System.out.print("Inside B.");
    }
}

問題:為什么輸出將是: x 但不是: Inside Bx

Bx的引用發出以下字節碼:

getstatic       #3   <Field int B.x>

根據Java虛擬機規范

Java虛擬機指示anewarray,checkcast,getfield, getstatic ,instanceof,invokedynamic,invokeinterface,invokespecial,invokestatic,invokevirtual,ldc,ldc_w,multianewarray,new,putfield和putstatic對運行時常量池進行符號引用 執行任何這些指令都需要解析其符號引用

因此JVM應該解析Bx符號引用 字段分辨率指定如下

要將未解析的符號引用從D解析為類或接口C中的字段,必須首先解析由字段引用給出的對C的符號引用(第5.4.3.1節)。

...

解析字段引用時,字段解析首先嘗試在C及其超類中查找引用的字段:

如果C聲明具有字段引用指定的名稱和描述符的字段,則字段查找成功。 聲明的字段是字段查找的結果。

否則,字段查找以遞歸方式應用於指定類或接口C的直接超接口。

否則,如果C具有超類S,則將字段查找遞歸地應用於S.

否則,字段查找失敗。

換句話說,JVM會將Bx解析為Ax 這就是為什么只需要加載A類的原因。

因為Bx實際上是Ax所以只需要加載A類。

§12.4JavaSE 7 規范Java語言規范的 “類和接口的初始化”指定:

類的初始化包括執行其static初始化程序和類中聲明的靜態字段(類變量)的初始化程序。

[...]

static字段(第8.3.1.1節 )的引用僅導致實際聲明它的類或接口的初始化,即使它可能通過子類的名稱,子接口或實現接口的類來引用。

因此,盡管 - 與上述某些答案中的聲明相反 - 必須加載 B類,為了確定BxA聲明, B類未初始化 (即,其static初始化器實際上並未運行),直到您做一些比B更具體的事情。

Class B擴展A ,它有一個public static variable x ,當你調用Bx時,它正在訪問

如果你期望Inside B. as out,你必須創建該類的Object。 執行所有靜態代碼塊。 或者將該靜態代碼塊移動到A類:-)

當JVM加載類時,它會對所有靜態塊進行分組,並按照它們聲明的順序執行它們。

編輯來源 ):簡短的回答是靜態不是用Java繼承的。 相反,在類中聲明的靜態成員(受“訪問”限制)在派生類的名稱空間中直接可見,除非它們在派生類中被聲明“隱藏”。

因此,如果靜態屬於類只有為什么它會逐漸滲透到派生類? 它不應該只停留在定義它的類中嗎?

它實際上並不需要加載B ,直到它訪問的靜態成員B直接。 注意這段代碼:

public class TestMain {
    public static void main(String[] args) {
        System.out.println(B.x);
        System.out.println(B.y);
    }

    static class A {
        public static String x = "x";
    }

    static class B extends A {
        public static String y = "y";
        static {
            System.out.print("Inside B.");
        }
    }
}

將輸出:

x
Inside B.y

因為它並不需要加載B ,直到東西B被訪問。

這是關於這個主題的一個很好的鏈接。 從文章“不要忘記,這個代碼將在JVM加載類時執行.JVM將所有這些塊組合成一個靜態塊然后執行。這里有幾點我想提一下:”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM