簡體   English   中英

在Java中加載類時真正發生了什么?

[英]What really happens when loading a class in java?

我對加載類的過程感到困惑。 類成員的執行順序是什么?

請參閱以下內容:

class L {

    static void fr(){
        a=1;
        b=3;
        a=b;
    }

    static{
        a=3;
        b=1;
        a=b;// here the problem:cannot reference a field before it is defined
    }

    static int a;
    static int b;

    public static void main(String args[]) {

    }
}

每當我將ab的聲明移到靜態塊之前的頂部時,編譯就可以正常工作。 因此,我需要了解這些東西如何解決上述問題。

在Java中,如果不是初始化類的表達式,則在聲明類變量之前先引用它是非法的。 Java將按文本順序在類中執行初始化程序。

JLS的12.4.2節規定:

接下來,以文本順序執行類的類變量初始化器和靜態初始化器,或者接口的字段初始化器,就好像它們是單個塊一樣。

JLS的第8.3.3節規定:

有時會限制使用聲明后在文本上出現的類變量,即使這些類變量在范圍內(第6.3節)。 具體而言,如果滿足以下所有條件,則是編譯時錯誤:

  • 使用類變量后,將在文本或類C中聲明類變量;

  • 在C的類變量初始值設定項或C的靜態初始值設定項中,此用法是一個簡單的名稱;

  • 用法不在作業的左側;

  • C是封閉使用的最里面的類或接口。

所有這些都是對的。 該聲明出現在使用后的a=b; 它在靜態初始化器中。 它不在作業的左側,而是最里面的(唯一的)類。

最簡單的編譯方法是將聲明移到源代碼中靜態初始化程序的上方。

有趣的是,替換a=b; 其中a=Lb; 也將得到此結果進行編譯,因為對b的引用不再“簡單”。

首先,加載類並驗證整體結構。 然后驗證方法並檢查外部鏈接。 然后執行靜態初始化。 這是執行靜態塊的時間。

但是您的問題顯然出在編譯器上,而不是類加載上。 您需要將靜態變量聲明向上移動到靜態塊上方。 與類加載完全無關。

提示:了解編譯時錯誤和運行時異常之間的區別。 您看到的是來自編譯器的錯誤消息。 (而且很幸運,您沒有遇到流血的地獄,並因為沒有在問題中包含EXACT錯誤消息而獲得投票。)

暫無
暫無

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

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