【问题标题】:Is `1/0` a constant expression in Java? [duplicate]`1/0` 是 Java 中的常量表达式吗? [复制]
【发布时间】:2015-09-21 06:59:42
【问题描述】:

据我了解,Java 8 JLS 表达式 (1/0) 被认为是一个常量表达式,但是当我尝试使用 OpenJDK 8 编译以下程序时出现错误

public class Switch {
    public static void main(String[] args) {
        switch(42) {
            case (1/0):
                return;
            default:
                return;
        }
    }
}

错误提示 (1/0) 不是常量表达式

Switch.java:4: error: constant expression required
            case (1/0):
                 ^
1 error

我错过了什么吗?还是 OpenJDK 8 中的错误?

【问题讨论】:

  • 您希望输入该案例的哪个值?!
  • 你真的不能除为零
  • 如果你做一些明智的事情会起作用吗,比如(1/2)
  • 1/0 将抛出 java.lang.ArithmeticException: / by zero 这可能是这个表达式不被视为 value 表示的原因

标签: java compiler-errors java-8 openjdk jls


【解决方案1】:

编译器正在进行常量折叠(预先计算琐碎的文字表达式)。这是表达式“突然完成”的情况,使用 JLS 措辞,使其不符合“常量表达式”的定义。所以这不是bug,和JLS是一致的。

是的,表达式也不会计算为值(警告用户尝试执行此类操作,结果将不是常量表达式),但编译器在尝试之前不知道这一点。不评估价值并突然完成似乎是齐头并进的。

添加变量声明,如

int x = 1 / 0;

不会导致编译器错误,它是强制在编译时计算表达式的开关。

顺便说一下,我检查了 Oracle 和 IBM JDK 的第 7 版也会发生这种情况,这不是 OpenJDK 或 JDK8 特定的。

【讨论】:

  • 是的,+1 用于正确强调 JLS 规范的 completes abruptly 部分。
  • @sstan 是的,我错过了常量表达式规范的那部分!
【解决方案2】:

常量表达式必须能够计算出一个值,因为编译器必须将该表达式重新转换为一个值。

1/0 没有任何价值。

来自 JSL §15.28:

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

【讨论】:

  • 我认为重点应该放在that does not complete abruptly 上,即抛出java.lang.ArithmeticException!很好的收获,谢谢!
  • 视情况而定,因为关键是如果它没有可评估的值,它会突然完成,在这种情况下就是这种情况。 “表示值”是更多与数学相关的约束,而突然完成则更多是实用约束。实际上甚至没有抛出异常,因为常量折叠是在编译而不是在执行期间完成的,这是一个真正的特殊情况。
  • 相反,您可以说它没有价值,因为它突然完成。 JLS 非常清楚表达式何时突然完成(例如整数除以零),而在定义表达式是/表示时使用表达式表示不是很好。 docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.6
  • 不,不管 Java,它都没有值,因此评估突然完成的事实与给该表达式一个值无关,en.wikipedia.org/wiki/Undefined_(mathematics)
  • 1.0 / 0.0 在 Java 中有一个值,与数学无关。
猜你喜欢
  • 1970-01-01
  • 2019-06-22
  • 2012-12-16
  • 1970-01-01
  • 2015-10-10
  • 2023-03-22
  • 2019-05-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多