12

重複の可能性:
1/0 は有効な 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 を評価しようとしたことを意味しますが、それはゼロによる除算であるため、そのまま通過させました。コンパイル時エラーなし。しかし、これは非常に奇妙に思えます...コンパイラは、それがゼロ除算であり、ランタイムがクラッシュすることを認識していますが、それでもコンパイルエラーにフラグを立てません!

誰かが私に理由を説明できますか?

4

2 に答える 2

7

をスローする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();

        }
    }
}
于 2011-02-12T20:15:54.857 に答える
2

JLS 15.28 定数式:

コンパイル時の定数式は、プリミティブ型の値を示す式、または突然完了しないString であり、以下のみを使用して構成されます。

...

したがって7/0、ゼロ除算により評価が突然完了するため、コンパイル時の定数ではありません。したがって、これは通常の実行時式として扱われ、実行時に例外がスローされます。

于 2011-02-12T20:21:58.923 に答える