2

假設我有下面一段代碼爲什麼java編譯器不能識別字段已被初始化?

int myVar; 
final boolean condition = <someCondition>; 
if (condition) { 
    myVar = 1; 
} 
if (condition) { 
    System.out.println("myVar = " + myVar); 
} 

當我編譯此,我得到了預期myVar might not have been initialized錯誤。 這是編譯器中的錯誤嗎?當condition爲真時很容易看到「myVar」被設置,並且僅在condition爲真時才被引用。 (condition也永遠不會重置)

P.S:對於那些對我的評論需要初始化爲0,是的,我意識到這一點。但問題是,我想「myVar的」要最終

+1

@imk這是相當明顯的OP已經知道,因爲這個問題的整點是關於*爲什麼*編譯器需要初始化。 – azurefrog

+4

Java編譯器根本沒有做足夠深入的分析,得出結論:在使用變量'myVar'之前,一個值總是被分配給變量'myVar'。一般來說,它不會嘗試關聯不同條件語句中的條件。 –

+0

我不認爲編譯器意識到這種情況不會改變。舉例來說,這是在一箇中斷的CPU上運行。條件可能會改變,當它回到執行此。 沒關係,我沒有看條件的聲明。 @JohnBollinger看起來足夠了。 – bhow

回答

4

初始化要求是Java的正式組成部分,如JLS描述(即值設置最多一次。):

對於局部變量或空白最終字段x的每次訪問,x必須在訪問之前明確分配,或發生編譯時錯誤。

JLS 8, chapter 16;重視在原)

的JLS接着說

分析考慮到了報表和 表達的結構;它還提供了對錶達式 運算符!,&&,||? :以及布爾值常數 表達式的特殊處理。

除條件布爾運算符 &&||,和? :和布爾值常量表達式,值 表達式中的特殊處理是沒有考慮到在流分析

(強調)

注意清楚conditionfinal不使其成爲「常量表達式」作爲規範定義了術語。本說明書中的推移,得到the specific rule for if statements

V是[未] if (e) S之後分配IFF V是[未]分配後SV是[未] e後分配時[e計算結果爲[false

在您的特定代碼,然後:

int myVar; 

myVar絕對是這裏分配。

final boolean condition = <someCondition>; 
if (condition) { 
    myVar = 1; 
} 

myVar是 「S後分配」,因爲S,該if語句體,進行無條件轉讓。 myVar而不是在評估條件後指定,但是,條件是否評估爲truefalse。因此,myVar在這個方法中沒有明確指定。

if (condition) { 

並沒有發生什麼變化,在這一點上:myVar仍然沒有明確至於JLS規則而言分配,因此它的價值不能被讀取。因此,編譯器有義務在未來的聲明報告錯誤:

System.out.println("myVar = " + myVar); 
} 
相關問題