下面的编译在我的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说什么?
>如果这是合法的,是否有一个很好的理由呢?
>这可能有什么好处?