2014-06-12 88 views
3
class Temp 
{ 
    public static void main(String[] args) 
    { 
     int x=10,y=20; 
     while (x<y) 
     { 
      System.out.println("Hello"); 
     } 
     System.out.println("Hi"); 
    } 
} 

輸出 它打印Hello無限次爲什麼java的最終變量表示不可達聲明

但是當我使局部變量最終詮釋X = 10,Y = 20; 然後它顯示聲明無法達到

回答

9

使這些變量final也使它們變量不變。這意味着編譯器可以用它們初始化的值替換變量的使用。

這樣,編譯器試圖產生以下

while (10 < 20) 

這相當於

while (true) 

這將使一個無限循環和隨之而來的塊之後將變得不可達的代碼。

這是在Java語言規範中規定,here

while語句可以正常完成且僅當 以下至少有一個爲真:

  • while語句是可到達並且條件表達式不是常量表達式(第15.28節),其值爲true。

  • 有一個可到達的break語句退出while語句。

這些都不是滿意的,所以while語句無法正常完成。它後面的一切都無法訪問。

+1

您可以通過在循環中放入一個if(somethingThatTheCompilerCannotReasonAbout)break;'來使其再次可達。 – Thilo

+1

也參考:http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4瞭解常量變量。如果你做int'a = 10; final int x = 10 + a;'那麼x不再是一個常量變量,甚至'while(x == x)'將在無限循環中執行。 – Shail016

+0

這是編譯器知道第二個println在變量爲最終時無法訪問的明確解釋。但是這留下了一個問題:爲什麼不能在變量可變時發現該行仍然無法訪問?循環體中沒有對它們的賦值,當然Java知道這樣的方法 - 局部變量不能在循環體中調用println的內部進行修改。那麼,如果條件不是恆定的,那麼編譯器就不會去評估可達性了嗎? (因爲,你知道,停止問題?) –

0

它的顯示,因爲兩個xy可達原因被宣佈final,也沒有辦法,他們會改變(他們是常數),所以同時將永遠循環,而「喜」的打印將永遠不會達到

0

Java知道最終變量不能改變。您宣佈x,y都是最終決定。因此它知道該循環不能終止,因爲x < y總是如此。

0

這是因爲在你的例子中最終變量是initialized with a compile-time constant expression。使它們成爲常量變量,編譯器知道它在運行時永遠不會被改變。因此final int x =10, y=20成爲編譯時已知的常量變量。

這相當於:

while (10<20){ 
     System.out.println("Hello"); 
    } 
    System.out.println("Hi"); 

現在編譯時評價告訴聲明System.out.println("Hi");會在這種情況下無法訪問。

其中non constant variables可以在運行時更改。所以沒有編譯時間檢查while條件。

更多參考:http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4

0

嗯,我覺得編譯器不會做數據流分析,因此,如果您正在使用xy內環路也不會檢查。

它是一種樂觀的方法。

編譯器假定你是一個好程序員,將在循環內改變值x(假設爲30),並且條件x < y將變爲false,並且循環將在循環執行後退出允許語句。

while (x<y) 
    { 
     System.out.println("Hello"); 
     //... at some point 
     x = 30; 
    } 

它是程序員的責任(像檢查異常是由編譯器檢查和未經檢查異常不作爲其程序員的責任)。

當您的變量final的編譯器知道,現在有辦法可以改變變量值

及本聲明while(x < y)將成爲等同於while(true)循環永遠不會退出和報表後循環將永遠不會得到執行

相關問題