以下は私のEclipseでうまくコンパイルされます:
final int j = 1/0;
// compiles fine!!!
// throws ArithmeticException: / by zero at run-time
Java は、最初から多くの「ダム コード」がコンパイルされるのを防ぎます (たとえば、コンパイルされ"Five" instanceof Number
ません!)。そのため、これが警告ほど生成されなかったという事実は、私にとって非常に驚きでした。コンパイル時に定数式を最適化できるという事実を考慮すると、陰謀は深まります。
public class Div0 {
public static void main(String[] args) {
final int i = 2+3;
final int j = 1/0;
final int k = 9/2;
}
}
上記のスニペットを Eclipse でコンパイルすると、次のバイトコードが生成されます ( javap -c Div0
)
Compiled from "Div0.java"
public class Div0 extends java.lang.Object{
public Div0();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_5
1: istore_1 // "i = 5;"
2: iconst_1
3: iconst_0
4: idiv
5: istore_2 // "j = 1/0;"
6: iconst_4
7: istore_3 // "k = 4;"
8: return
}
ご覧のとおり、i
およびk
代入はコンパイル時の定数として最適化されていますが、除算0
(コンパイル時に検出可能である必要があります) はそのままコンパイルされます。
javac 1.6.0_17
はさらに奇妙な動作をし、サイレントにコンパイルしますが、割り当てをバイトコードi
から完全に削除しk
ます (おそらく、それらがどこにも使用されていないと判断したためです)。1/0
質問は次のとおりです。
1/0
実際、いつでもどこでもコンパイルできる正当な Java 式ですか ?- JLSはそれについて何と言っていますか?
- これが合法である場合、それには正当な理由がありますか?
- これは何の役に立つのでしょうか?