Java 访问未定义值后Nashorn中的输出不一致
我正在尝试使用Nashorn创建Java程序的控制台接口。因此,我希望根据一些默认导入对一些输入进行评估。问题是当它访问未定义的值时。理想情况下,Java 访问未定义值后Nashorn中的输出不一致,java,nashorn,Java,Nashorn,我正在尝试使用Nashorn创建Java程序的控制台接口。因此,我希望根据一些默认导入对一些输入进行评估。问题是当它访问未定义的值时。理想情况下,engine.eval应该抛出一个ReferenceError,或者返回null,但我稍后会得到不一致的值: import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class Main { public static void mai
engine.eval
应该抛出一个ReferenceError
,或者返回null
,但我稍后会得到不一致的值:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
System.out.println(engine.eval("with(JavaImporter(java.util)) { x }"));
System.out.println(engine.eval("with(JavaImporter(java.util)) { x = 1 }"));
System.out.println(engine.eval("with(JavaImporter(java.util)) { x }"));
}
}
在Windows和Oracle JDK 1.8.0_101上的结果是:
null
1
null
最后一个输出是null
,但是添加x==null
会得到false
如果在第一个字符串中添加空格,则会得到此输出:
null
1
1
如果第一个和最后一个engine.eval
参数(包括空格)完全相同,则最后一个值似乎是null
x
的值可以返回到null
和1
之间,因此它看起来像引擎中的某种缓存:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class Main {
public static void main(String[] args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
System.out.println(engine.eval("with(JavaImporter(java.util)) { x }"));
System.out.println(engine.eval("with(JavaImporter(java.util)) { x = 1 }"));
System.out.println(engine.eval("with(JavaImporter(java.util)) { x }"));
System.out.println(engine.eval("with(JavaImporter(java.util)) { x }"));
System.out.println(engine.eval("with(JavaImporter(java.util)) { x + x }"));
System.out.println(engine.eval("with(JavaImporter(java.util)) { x }"));
}
}
给出:
null
1
null
1
2.0
null
是否有办法使其一致地给出
null,1,1
结果?强制引擎确认变量的声明
只需在第一个脚本中使用var x
System.out.println(engine.eval(“with(JavaImporter(java.util)){var x}”);
System.out.println(engine.eval(“with(JavaImporter(java.util)){x=1}”);
System.out.println(engine.eval(“with(JavaImporter(java.util)){x}”)代码>强制引擎确认变量的声明
只需在第一个脚本中使用var x
System.out.println(engine.eval(“with(JavaImporter(java.util)){var x}”);
System.out.println(engine.eval(“with(JavaImporter(java.util)){x=1}”);
System.out.println(engine.eval(“with(JavaImporter(java.util)){x}”)代码>引擎中有一个类缓存,可以通过以下方式创建它来禁用它:
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new String[] { "--class-cache-size = 0" });
通过强制重新编译每个表达式,似乎可以解决问题。根据作用域中的变量,同一表达式的编译方式似乎有所不同。引擎中有一个类缓存,可以通过以下方式将其禁用:
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new String[] { "--class-cache-size = 0" });
通过强制重新编译每个表达式,似乎可以解决问题。根据作用域中的变量,同一表达式的编译方式似乎有所不同。x
的值未定义,而不是null。它只是通过engine.eval
转换为null,以便将其返回到java。你有没有试过x===未定义的
(注意===
而不是==
,==
在javascript中只是…不好。它有非常不一致的行为)?。我使用=
来包含它是未定义的
或空的可能性,但我使用什么代码并不重要,任何更改,它将再次被视为1
。将x
替换为x+x
得到2,甚至在x
周围添加空格也得到1。这就像字符串的结果被引擎缓存,它忽略了对值的任何更改。我认为这可能是nashorn在返回到非严格模式时出现的错误(尽管我没有找到任何引用)。重要的是要注意,with(…){…}
语法已被弃用,并且不受的“use strict”支持代码>。完全删除with
语句会使nashorn抱怨变量未声明。x
的值未定义,不是null。它只是通过engine.eval
转换为null,以便将其返回到java。你有没有试过x===未定义的
(注意===
而不是==
,==
在javascript中只是…不好。它有非常不一致的行为)?。我使用=
来包含它是未定义的
或空的可能性,但我使用什么代码并不重要,任何更改,它将再次被视为1
。将x
替换为x+x
得到2,甚至在x
周围添加空格也得到1。这就像字符串的结果被引擎缓存,它忽略了对值的任何更改。我认为这可能是nashorn在返回到非严格模式时出现的错误(尽管我没有找到任何引用)。重要的是要注意,with(…){…}
语法已被弃用,并且不受的“use strict”支持代码>。完全删除with
语句会使nashorn抱怨没有声明变量。