以下在我的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."":()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对此有何评论?
如果这是合法的,那么有充分的理由吗? 这可能有什么好处?