Nashorn 不再使用 BigDecimal
Nashorn no longer working with 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
现在 returns object
以前 return number
.
我的问题是这种行为是故意的还是错误?我首先认为这是一个错误,但 JDK-8010732 似乎另有建议。
Nashorn 的初始版本将所有数字 Java 基元和 java.lang.Number 的所有子 class 视为 Java 脚本编号。但是,Java脚本数字定义为双精度,这意味着不映射到双精度的数字类型(例如 long 或 java.lang.BigDecimals)在转换为 Java 时将遭受精度损失剧本编号。
如您所见,我们在 8u77 和 8u92 之间修复了此问题。 java.lang.Number 无法完全映射到双打的实例在 Nashorn 中不再被视为 Java 脚本编号。
您有两种选择来解决这个问题。一种是将这些数字视为 Java 对象并使用 Java class 提供的方法。这通常是更好的选择,因为 Java class 是为处理手头的数字类型而编写的。另一种选择是显式转换为 Java 脚本编号。这通常是通过在不使用 "new" 关键字的情况下调用全局 Number() 构造函数来完成的,或者只需在一元“+”运算符前面加上。但是请注意,此转换可能会导致精度损失,而您不会注意到,因此第一个选项可能是更安全的路径。
我们从 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
现在 returns object
以前 return number
.
我的问题是这种行为是故意的还是错误?我首先认为这是一个错误,但 JDK-8010732 似乎另有建议。
Nashorn 的初始版本将所有数字 Java 基元和 java.lang.Number 的所有子 class 视为 Java 脚本编号。但是,Java脚本数字定义为双精度,这意味着不映射到双精度的数字类型(例如 long 或 java.lang.BigDecimals)在转换为 Java 时将遭受精度损失剧本编号。
如您所见,我们在 8u77 和 8u92 之间修复了此问题。 java.lang.Number 无法完全映射到双打的实例在 Nashorn 中不再被视为 Java 脚本编号。
您有两种选择来解决这个问题。一种是将这些数字视为 Java 对象并使用 Java class 提供的方法。这通常是更好的选择,因为 Java class 是为处理手头的数字类型而编写的。另一种选择是显式转换为 Java 脚本编号。这通常是通过在不使用 "new" 关键字的情况下调用全局 Number() 构造函数来完成的,或者只需在一元“+”运算符前面加上。但是请注意,此转换可能会导致精度损失,而您不会注意到,因此第一个选项可能是更安全的路径。