将 JavaScript 函数编译成可调用的 Java 对象?
Compile JavaScript function into a callable Java object?
假设我的文本定义了一个有效的Java脚本函数,像这样:
function sum(x, y) {
return x + y
}
我希望能够编写 Java 代码,将文本编译成可调用实体,这样:
- 我的 Java 代码可以发现编译实体是一个 函数 而不是任意脚本。
- 我的Java代码可以发现函数有多少参数。
- 我可以通过为所有参数提供数据绑定来调用来自Java的函数。
我原以为 javax.script 包会提供实现此目的的代码,但我这辈子都看不到如何实现。我将如何编写 Java 代码来完成我上面描述的内容。
要 Java 调用那个 Java 脚本函数,您首先要评估脚本,然后扫描全局范围内的变量以查找函数。
您可以调用这些函数,但您无法获取参数。为此,您必须自己解析函数头。
Java8-14使用Nashorn引擎。这里是一个例子,有多种定义函数的方法,所以你可以在函数头中看到不同之处。
import java.util.Map.Entry;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import jdk.nashorn.api.scripting.JSObject;
String script = "function sum(x, y) {\n" +
" return x + y\n" +
"}\n" +
"function diff() {\n" +
" return arguments[0] - arguments[1]\n" +
"}\n" +
"mult = function(x, y) {\n" +
" return x * y\n" +
"}\n";
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Bindings vars = engine.createBindings();
engine.eval(script, vars);
for (Entry<String, Object> var : vars.entrySet()) {
String name = var.getKey();
Object value = var.getValue();
if (value instanceof JSObject) {
JSObject jsObj = (JSObject) value;
if (jsObj.isFunction()) {
String funcHeader = jsObj.toString().replaceFirst("(?s)\{.*", "");
System.out.println("function '" + name + "' defined as: " + funcHeader);
System.out.println(name + "(5,7) = " + jsObj.call(null, 5, 7));
}
}
}
输出
function 'sum' defined as: function sum(x, y)
sum(5,7) = 12.0
function 'diff' defined as: function diff()
diff(5,7) = -2.0
function 'mult' defined as: function(x, y)
mult(5,7) = 35.0
假设我的文本定义了一个有效的Java脚本函数,像这样:
function sum(x, y) {
return x + y
}
我希望能够编写 Java 代码,将文本编译成可调用实体,这样:
- 我的 Java 代码可以发现编译实体是一个 函数 而不是任意脚本。
- 我的Java代码可以发现函数有多少参数。
- 我可以通过为所有参数提供数据绑定来调用来自Java的函数。
我原以为 javax.script 包会提供实现此目的的代码,但我这辈子都看不到如何实现。我将如何编写 Java 代码来完成我上面描述的内容。
要 Java 调用那个 Java 脚本函数,您首先要评估脚本,然后扫描全局范围内的变量以查找函数。
您可以调用这些函数,但您无法获取参数。为此,您必须自己解析函数头。
Java8-14使用Nashorn引擎。这里是一个例子,有多种定义函数的方法,所以你可以在函数头中看到不同之处。
import java.util.Map.Entry;
import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import jdk.nashorn.api.scripting.JSObject;
String script = "function sum(x, y) {\n" +
" return x + y\n" +
"}\n" +
"function diff() {\n" +
" return arguments[0] - arguments[1]\n" +
"}\n" +
"mult = function(x, y) {\n" +
" return x * y\n" +
"}\n";
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Bindings vars = engine.createBindings();
engine.eval(script, vars);
for (Entry<String, Object> var : vars.entrySet()) {
String name = var.getKey();
Object value = var.getValue();
if (value instanceof JSObject) {
JSObject jsObj = (JSObject) value;
if (jsObj.isFunction()) {
String funcHeader = jsObj.toString().replaceFirst("(?s)\{.*", "");
System.out.println("function '" + name + "' defined as: " + funcHeader);
System.out.println(name + "(5,7) = " + jsObj.call(null, 5, 7));
}
}
}
输出
function 'sum' defined as: function sum(x, y)
sum(5,7) = 12.0
function 'diff' defined as: function diff()
diff(5,7) = -2.0
function 'mult' defined as: function(x, y)
mult(5,7) = 35.0