[英]final variable initialized first
我在這里閱讀這個問題: Java:初始化靜態最終字段的順序是什么?
根據答案
“除了最終的類變量和接口的字段,其值是編譯時常量首先被初始化......”
我認為這是不正確的,因為以下將失敗:
static {
String y = x;
}
public static final String x = "test";
在靜態塊中,無法識別x
。 如果答案是正確的,有人可以評論嗎?
初始化順序不會改變JLS在各種情況下聲明變量之前不允許引用變量的事實。 這在JLS§8.3.3中描述:
使用聲明在使用后以文本形式出現的類變量有時會受到限制,即使這些類變量在范圍內(第6.3節)。 具體來說,如果滿足以下所有條件,則為編譯時錯誤:
在使用類變量之后,類或接口C中的類變量聲明以文本形式出現;
在C的類變量初始化程序或C的靜態初始化程序中使用是一個簡單的名稱;
使用不在作業的左側;
C是封閉使用的最內層類或接口。
這就是你的代碼得到這個編譯erorr的原因:
錯誤:非法轉發參考
首先初始化作為常量變量的靜態字段的聲明確實在JLS§12.4.2中定義:
否則,記錄當前線程正在進行C的Class對象初始化並釋放LC的事實。
然后,初始化C的靜態字段,它們是常量變量(§4.12.4,§8.3.2,§9.3.1)。
...
- 接下來,按文本順序執行類的類變量初始值設定項和類的靜態初始值設定項,或接口的字段初始值設定項,就好像它們是單個塊一樣。
如您所見,常量變量在步驟6中初始化,但在步驟9中初始化。
這表明了這種行為:
public class Example {
static String y;
static {
y = foo();
}
static String foo() {
return x.toUpperCase();
}
public static final String x = "test";
public static void main(String[] args) throws Exception {
System.out.println(x);
System.out.println(y);
}
}
編譯並輸出:
test TEST
如果你更改了x
行,那么它就不再是常數了:
public static final String x = Math.random() < 0.5 ? "test" : "ing";
它編譯,但隨后將失敗,因為x
是null
為y = foo();
。
為避免疑義:我不建議使用方法來初始化這樣的字段。 :-)
正如這個答案所述:
......它們按照它們出現在源中的順序進行初始化。
你是絕對正確的,你的例子失敗了,因為你試圖使用在使用之后聲明的變量。 由於靜態塊是按源代碼的順序執行的,因此您絕對正確,應該建議並編輯該答案,因為此語句無效:
除了最后的類變量...首先被初始化。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.