注意:以下内容是针对Java 8,使用Nashorn引擎。
首先,为了使代码编译通过,请从println()
语句中删除.value
。 obj
被声明为Object
类型,而Object
没有value
字段。
一旦您这样做了,运行代码时会得到以下异常:
Exception in thread "main" javax.script.ScriptException: <eval>:1:25 Invalid return statement
var obj = { value: 1 }; return obj;
^ in <eval> at line number 1 at column number 25
这是因为你没有一个函数,所以你不能调用return
。脚本的返回值是最后一个表达式的值,所以只需说obj
。
现在它将运行并打印[object Object]
。如果要查看您得到的对象的类型,请更改为println(obj.getClass().getName())
。这将打印jdk.nashorn.api.scripting.ScriptObjectMirror
。我已经链接到了您方便使用的javadoc文档。
ScriptObjectMirror
实现Bindings
,而Bindings
又实现了Map <String, Object>
,因此您可以调用get("value")
。
工作代码如下:
import javax.script.*;
public class Test {
public static void main(String[] args) throws ScriptException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Bindings obj = (Bindings)engine.eval("var obj = { value: 1 }; obj; ");
Integer value = (Integer)obj.get("value");
System.out.println(value);
}
}
更新
整个重点是创建一个带有函数的对象,这个引擎是否支持?没有 Function 对象。
以下是如何实现的示例:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
public class Test {
public static void main(String[] args) throws Exception {
String script = "var f = {\n" +
" value: 0,\n" +
" add: function(n) {\n" +
" this.value += n;\n" +
" return this.value;\n" +
" }\n" +
"};\n" +
"f; // return object to Java\n";
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
ScriptObjectMirror obj = (ScriptObjectMirror)engine.eval(script);
System.out.println("obj.value = " + obj.getMember("value"));
System.out.println("obj.add(5): " + obj.callMember("add", 5));
System.out.println("obj.add(-3): " + obj.callMember("add", -3));
System.out.println("obj.value = " + obj.getMember("value"));
}
}
输出
obj.value = 0
obj.add(5): 5.0
obj.add(-3): 2.0
obj.value = 2.0
return obj;
,它还能正常工作吗?返回语句应该在函数中使用,但我不知道该类如何评估JS代码。 - user1106925var
语句不会返回对象本身,只有用括号包裹的对象才能生效。这些括号对于一个有效的程序来说是必要的。 - user1106925println()
语句的注释中提到的“无效令牌错误”),而不是运行时错误。请参阅我的答案以了解原因。 - Andreasvar obj = { value: 1 };
和{value: 1};
两者都不太可能起作用,因为单独的任何一个语句都无法产生一个对象,而({value: 1})
则可以。 - user1106925