12

可能重複:
Is 1/0 a legal Java expression?爲什麼Java常量除以零產生編譯時錯誤?

爲什麼這段代碼編譯?

class Compiles { 
    public final static int A = 7/0; 
    public final static int B = 10*3; 

    public static void main(String[] args) {} 
} 

如果我看看編譯後的類文件,我可以看到B被評估爲30,而A仍然是7/0。

就我所瞭解的JSL而言,除以零的表達式不是常數。

價:JLS 15.28

我的上述說法是由於這一行:

編譯時常量表達式是表示原語類型的值

因此通過將表達式零不計算爲原始值。

我真的不明白爲什麼編譯器允許這個呢?只是要清楚,我的代碼崩潰與運行時「java.lang.ExceptionInInitializerError」

在我看來,編譯器威脅任何最終的靜態變量作爲常量,並評估它的編譯時間。這意味着編譯器已經試圖評估A,但由於它是一個零分區,它只是讓它通過。沒有編譯時錯誤。但是,這看起來非常奇怪......編譯器知道它被零除,並且它會使運行時崩潰,但它不會標記編譯錯誤!

任何人都可以向我解釋爲什麼?

+1

是否有任何除零生成編譯時錯誤的實例?如果你在正常的程序代碼中被零除,你會在運行時得到一個`ArithmeticException`,所以我也沒有看到這個通過編譯器的事情。 – BoltClock 2011-02-12 20:20:02

回答

6

拋出java.lang.ExceptionInInitializerError是唯一正確的行爲。

如果你的代碼沒有編譯完成,一個完全有效的Java程序將被拒絕,那就是一個錯誤。

7/0放入編譯代碼中的唯一正確替代方案實際上是明確拋出ExceptionInInitializerError,但是更有用嗎?

編譯器知道它被零除並且它會崩潰運行時,但它卻會標記編譯錯誤!

其實,我不同意這種說法......將這項計劃崩潰

class Compiles { 
    public final static int A = 7/0; 
    public final static int B = 10*3; 

    public static void main(String[] args) {} 

} 

public class Test { 

    // Application entry point. 
    public static void main(String[] args) { 
     try { 
      new Compiles(); 

      launchTheMissiles(); 

     } catch (ExceptionInInitializerError e) { 

      doUsefulStuff(); 

     } 
    } 
} 
+0

你的程序不會崩潰。但我的意志。所以你總是會把新對象的初始化放在try/catch中? – laitinen 2011-02-12 20:32:19

+1

是的。我總是把try/catch放在`ExceptionInitializerError`類的實例化中。 ;-D – aioobe 2011-02-12 20:35:05

2

JLS 15.28 Constant Expression

編譯時常量表達式是一個表達式表示原始類型或String 的值,該值不會突然完成並且使用僅由以下內容:

...

因此7/0是不是一個編譯時間常數,因爲它的評估由於被零除而突然完成。所以,它被視爲一個常規的運行時表達式,並在運行時拋出一個異常。

相關問題