为什么这段代码会编译?
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,但由于它是零除以它只是让它通过。没有编译时错误。但这看起来非常奇怪...编译器知道它是零除以它会崩溃运行时但是它不会标记编译错误!
任何人都可以向我解释原因吗?
答案 0 :(得分: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();
}
}
}
答案 1 :(得分:2)
JLS 15.28 Constant Expression:
编译时常量表达式是表示基本类型值的表达式或不突然完成的字符串 ,仅使用以下内容组成:
...
因此7/0
不是编译时常量,因为它的评估由于除零而突然完成。因此,它被视为常规运行时表达式,并在运行时抛出异常。