我在 java8 中使用“nashorn”javascript 引擎在运行时评估一些表达式。我有一个 util 类,方法如下:
public static String evaluateJavaScriptExpression(String expression) throws ScriptException {
if (expression == null) {
return null;
}
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine javaScriptEngine = scriptEngineManager.getEngineByName(JAVASCRIPT_ENGINE);
return String.valueOf(javaScriptEngine.eval(expression));
}
为此我创建了一些单元测试。其中之一是这样的:
String expression = "var arr = [1, 3, 2, 5, 4]; arr.indexOf(0);";
assertEquals("-1", ExpressionEvaluatorUtil.evaluateJavaScriptExpression(expression));
当我使用java版本“1.8.0_91”时,它对我来说工作得很好。但是使用java版本“1.8.0_92”的人报告测试失败。我将版本切换到 build 92,但它对我来说也失败了。其实际结果是“-1.0”。
另外,我在 Chrome 控制台中尝试了相同的 js 代码,它返回与 build 91 中一样的“-1”。
有谁知道为什么两个jdk版本的结果有这么大的差异?这是一个错误还是故意更改的?
好吧,如果您知道更改的确切版本号,您就知道在哪里查找:1.8u92 错误修复列表 http://www.oracle.com/technetwork/java/javase/2col/8u92-bugfixes-2949473.html列出了一些有关 Nashorn 的修复,其中最有趣的是JDK-8144020 https://bugs.openjdk.java.net/browse/JDK-8144020:
删除 long 作为内部数字类型
ECMA 将 double 定义为 JavaScript 中唯一的数字类型。在 Nashorn 中,我们在内部将数字表示为 int、long 和 double。使用 long 是有问题的,因为它为 double 提供的 53 位增加了额外的精度。 ……
乍一看,这似乎只是一个内部变化,但如果你意识到你之前的结果源于之前的事实,那么情况就会改变,eval
返回了一个Long
对于此代码,格式为"-1"
.
现在考虑这个错误报告的第一句话:“ECMA 将 double 定义为 JavaScript 中唯一的数字类型”。这得出的结论是返回一个Long
不是指定的结果类型,而是实现工件。
所以显然,当long
已从内部使用中删除,可以返回Long
已被淘汰,引擎现在无法恢复Integer
相反,但是Double
,作为变革的副产品。
这解释了为什么还有其他脚本"var str = 'abcd'; str.indexOf('x');"
仍然会产生没有小数位的输出。后一个脚本评估为Integer
现在仍然如此。由于输出类型的变化是删除内部的副产品long
用法,而不是有意改变所有非Double
数值结果,内部使用int
没有受到影响。
当将结果与 Chrome 引擎进行比较时,您必须考虑到您只是比较格式化输出,数字到字符串的转换不是脚本的一部分。所以结果是未知的。浏览器可以自由地呈现与没有小数位的整数值匹配的所有数值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)