为什么 Java 常量除以零不会产生编译时错误?

发布于 2024-10-17 09:38:08 字数 931 浏览 12 评论 0原文

可能的重复:
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,但由于它被零除,所以就让它通过。没有编译时错误。但这看起来非常非常奇怪......编译器知道它是除以零并且它会导致运行时崩溃,但它不会标记编译错误!

谁能向我解释为什么?

Possible Duplicate:
Is 1/0 a legal Java expression?

Why does this code compile?

class Compiles {
    public final static int A = 7/0;
    public final static int B = 10*3;

    public static void main(String[] args) {}
}

If I take a look in the compiled class file, I can see that B has been evaluated to 30, and that A still is 7/0.

As far as I understand the JSL an expression where you divide by zero is not a constant.

Ref: JLS 15.28

My above statement is due to this line:

A compile-time constant expression is an expression denoting a value of primitive type

Hence dividing by zero is not evaluated to a primitive value.

What I really dont understand is why the compiler allows this anyway? Just to be clear, my code above crashes runtime with a "java.lang.ExceptionInInitializerError"

As it seems to me the compiler threats any final static variable as a constant and evaluates it compile time. That means that the compiler already has tried to evaluate A, but since it was a division by zero it just let it go through. No compile time error. But this seems very very bizarre... The compiler knows it is a divide by zero and that it will crash runtime but nevertheless it doesn't flag a compile error!

Can anyone explain to me why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不回头走下去 2024-10-24 09:38:08

抛出 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();

        }
    }
}

To throw an java.lang.ExceptionInInitializerError is the only correct behavior.

If your code did not compile, a perfectly valid Java program would have been rejected, and that would have been a bug.

The only correct alternative to putting 7/0 in the compiled code, would actually be to explicitly throw a ExceptionInInitializerError, but how much more useful is that?

The compiler knows it is a divide by zero and that it will crash runtime but nevertheless it does flag a compile error!

Actually, I wouldn't agree with that... would this program crash?

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();

        }
    }
}
故事与诗 2024-10-24 09:38:08

JLS 15.28 常量表达式

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

...

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

JLS 15.28 Constant Expression:

A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

...

Therefore 7/0 is not a compile-time constant, since its evaluation completes abruptly due to division by zero. So, it's treated as a regular run-time expression, and throws an exception in runtime.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文