【问题标题】:Why is "Infinity" generated for #{1/0} in EL with JSF?为什么使用 JSF 在 EL 中为 #{1/0} 生成“Infinity”?
【发布时间】:2018-07-21 06:21:11
【问题描述】:

我需要一个页面来为实验抛出异常并添加

#{1/0}

index.xhtml。我预计会抛出一个java.lang.ArithmeticException,但是表达式在生成的页面上评估为字符串Infinity。除零没有定义,NaN 可能是比 Infinity 更好的选择,但即使是 NaN 也令人困惑,因为它在 Java 编程语言中不直观,其中除零是通过异常而不是返回来处理的价值。

跑步

@PostConstruct
public void init() {
    int x = 1/0;
}

在支持 bean 中导致预期的 java.lang.ArithmeticException: / by zero

除了解释为什么会发生这种情况之外,我还对抛出异常的方法感兴趣,因为我更喜欢在开发过程中应用程序的早期和严重崩溃,而不是显示逻辑(或因此不合逻辑的)字符串。

我仔细检查了潜在重复的大列表(x/0 == NaN 其他语言等),但似乎还没有对 JSF 的解释。我不是在寻找任何形式的解决方案(没有问题,我只是偶然发现了这种行为),而是一个解释。

我在使用 Primefaces 6.2 时遇到过这种情况。

【问题讨论】:

  • JSF 使用double 数据类型进行数值计算。它的行为与 Java 对双精度的行为以及相应的 IEEE 标准一致。 1/0 是正无穷大,-1/0 是负无穷大,0/0 是未定义(NaN)
  • @ErwinBolwidt 很好的解释,谢谢。您可以将其发布为答案。那么可能没有办法抛出异常。
  • 您可以尝试在其周围添加custom function,在其中检查字符串“Infinity”并引发错误

标签: java jsf el


【解决方案1】:

表达式语言 3.0 规范第 1.7.1 节对此进行了解释:

"二元运算符-A {/,div} B

  • 如果ABnull,返回(Long)0
  • 如果ABBigDecimalBigInteger,则强制转换为BigDecimal 并返回A.divide(B, BigDecimal.ROUND_HALF_UP)
  • 否则,将 AB 强制转换为 Double 并应用运算符
  • 如果运算符导致异常,则错误。”

在这种情况下,AB 是整数,因此它们被强制转换为 Double,并且使用 IEE 754 浮点算术执行除法...导致 INF

那么可能没有办法抛出异常。

有办法:

  • 如果 AB(但不是两者)都是 null,则规范暗示您将获得 NPE。
  • BigIntegerBigDecimal 情况下,如果B 为零,divide 方法应该抛出一个ArithmeticException

参考:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 2015-12-24
    相关资源
    最近更新 更多