[英]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[]) {
}
}
每當我將a
和b
的聲明移到靜態塊之前的頂部時,編譯就可以正常工作。 因此,我需要了解這些東西如何解決上述問題。
在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.