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实际上是显式抛出 a 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 常量表达式

编译时常量表达式是表示原始类型值或字符串的表达式,它不会突然完成并且仅使用以下内容组成:

...

因此7/0不是编译时常量,因为它的评估由于被零除而突然完成。因此,它被视为常规运行时表达式,并在运行时引发异常。

于 2011-02-12T20:21:58.923 回答