【问题标题】:Why does Java 8 Nashorn (JavaScript) modulo returns 0.0 (double) instead of 0 (integer)?为什么 Java 8 Nashorn (JavaScript) 取模返回 0.0 (double) 而不是 0 (integer)?
【发布时间】:2014-11-17 08:06:22
【问题描述】:

考虑以下代码示例:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Tester {

  public static void main( String[] args ) throws Exception {
      ScriptEngine se = new ScriptEngineManager().getEngineByName( "nashorn" );

      Object eval = se.eval( "5%5" );

      System.out.println( "eval = " + eval );
      System.out.println( "eval.getClass() = " + eval.getClass() );
  }
}

为什么会产生以下输出?

评估 = 0.0
eval.getClass() = class java.lang.Double

结果类型是java.lang.Double,这是奇怪的

如果余数不为 0,则正确返回 java.lang.Integer,例如5%2 返回java.lang.Integer' with value1`。

只有 0 有点特殊

在 Firefox 32.0.2(FindBugs 控制台)中尝试相同的 JavaScript 表达式可以正常工作并返回纯 0。

有没有办法强制 Nashorn 返回 Integer 类型而不是 Double?

【问题讨论】:

  • JavaScript 只有浮点数类型。
  • @Teemu 感谢您的意见,但这里为什么重要?在内部它可能是一个浮点数,但它能够以某种方式将它“转换”为整数,例如5%2 产生整数 1。如果在这种情况下得到 1.0,我会接受这样的解释。
  • Firefox 没有“投射”任何东西。这只是它如何显示浮点值 1.0 的问题。
  • 好的,我想我们在这里有点偏离轨道。忘记铸造/火狐等。仍然有效的问题是为什么5%2导致java.lang.Integer(1)5%5导致java.lang.Double(0.0)

标签: javascript java-8 modulo nashorn


【解决方案1】:

8u40 - 即将更新 - 来源 http://hg.openjdk.java.net/jdk8u/jdk8u-dev/nashorn 修复了这个问题。也就是说,最好期待“java.lang.Number”(在 Java 接口中)类型的结果用于数值计算并使用 java.lang.Number 方法(如 intValue()、doubleValue() 等)进行转换。

【讨论】:

  • 非常感谢您的意见!真的很遗憾我不能接受你们所有的答案。我已经接受了大卫的回答,因为他首先建议这是一个错误并深入研究源代码。不过,再次感谢。
【解决方案2】:

JavaScript 中没有整数。

ECMAScript Section 8: Types开头:

ECMAScript 语言类型有 Undefined、Null、Boolean、String、 数字和对象。

那就见ECMAScript Section 8.5: The Number Type

Number 类型正好有 18437736874454810627(即 264−253+3)个值, 表示双精度 64 位格式 IEEE 754 值...”(已添加重点)

Firefox 将浮点值 1 显示为“1”而不是“1.0”这一事实无关紧要,这会让您感到困惑。

【讨论】:

  • 感谢您的回答。让我们忘记 Firefox,因为我同意它可能会混淆。让我们只关注应该实现 ECMAScript LS 的 Nashorn。有时是java.lang.Integer,有时是java.lang.Double
  • 太好了:感谢您将问题缩小到...问题。这就是我要说的:鉴于所有 JavaScript 数字都是浮点数,它返回 java.lang.Integer 很奇怪。我会看看我能不能弄清楚那部分。我会说这是一个错误,可能会在未来的版本中发生变化,因此我可能会将我的东西包装在将所有内容转换为 Double 的东西中(我面前没有 Java API,但是 new Double() 或 Double .valueOf() 或其他)。
  • 或者,为了更清楚,我会将问题从“为什么返回 Double 而不是 Integer”更改为“为什么返回 Integer 而不是 Double?”
  • 好的,非常感谢大卫。因此,Nashorn 的实现者所做的结果类型是 Integer 或 Double 之间的区别可能非常具有误导性。我希望它能够始终如一地工作——要么它应该一直进行转换(所以在上面的问题中它应该总是java.lang.Integer)或者它应该省略任何转换并只返回java.lang.Double
  • 是的。我查看了代码,设计使它看起来,在我的学习水平上,返回一个 Double 可能是意图。源代码见hg.openjdk.java.net/nashorn/jdk8/nashorn/file/18edd7a1b166/src/…rem(实现%)的返回值是Type.NUMBER,如果你访问(同一个包)Type.java,你会看到它与Double相关联。但是您会在 NumberType 中看到,我们使用所有 visitInsn 和 OpCode 内容进入字节码领域,这就是我现在下车的地方。 :)
【解决方案3】:

这就是Nashorn docs 关于将数值从 JavaScript 传递到 Java 的说法:

如果目标类型不太具体(例如,数字),您只能期望它们是数字类型,...由于内部优化,数字可以是任何盒装类型

正如其他人已经指出的那样,JavaScript 本身只支持浮点值(Number 类型)。

【讨论】:

  • 非常感谢这个“由于内部优化,数字可以是任何盒装类型”部分!
猜你喜欢
  • 1970-01-01
  • 2013-10-03
  • 1970-01-01
  • 2016-07-31
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多