Nashorn不再使用BigDecimal

菲利普·元帅:

我们从Oracle JDK 8u77升级到8u92,突然以前无法运行的脚本不再起作用。最小的复制器是:

Map<String, Object> attributes = Collections.singletonMap("GROSSREIMBAMOUNT", BigDecimal.ZERO);
String script = "GROSSREIMBAMOUNT.toFixed(2)";

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");

for (Entry<String, Object> entry : attributes.entrySet()) {
  jsEngine.put(entry.getKey(), entry.getValue());
}

System.out.println(jsEngine.eval(script));

以前我们有

0.00

但是现在我们得到了。

TypeError: GROSSREIMBAMOUNT.toFixed is not a function

typeof现在返回object以前返回的位置number

我的问题是这种行为是故意的还是错误?我首先虽然这将是一个错误,但JDK-8010732似乎暗示了其他问题。

汉尼斯·沃诺夫(HannesWallnöfer):

Nashorn的初始发行版将所有数字Java原语和java.lang.Number的所有子类都视为JavaScript数字。但是,JavaScript数字定义为双精度型,这意味着不能转换为双精度型的数字类型(例如long或java.lang.BigDecimals)在转换为JavaScript数字时会失去精度。

如您所见,我们将其固定在8u77和8u92之间。无法干净地映射为double的java.lang.Number实例在Nashorn中不再被视为JavaScript数字。

您可以通过两种方法解决此问题。一种是将这些数字视为Java对象,并使用Java类提供的方法。通常,这是更好的选择,因为Java类是为与手头的数字类型一起使用而编写的。另一个选择是显式转换为JavaScript数字。通常,可以通过调用不带“ new”关键字的全局Number()构造函数来完成此操作,也可以仅在前加一元“ +”运算符。但是请注意,这种转换可能会导致精度损失,而不会引起您的注意,因此第一种选择可能是更安全的路径。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章