以数组为参数的Java和Javascript绑定函数
我正在努力做到以下几点。 Java应用程序应该通过ScriptEngineManager/ScriptEngine运行javascript,并且javascript应该能够调用Java应用程序中的函数。只要只传递一个简单的变量,这种方法就非常有效。但我不能让它通过数组。 这是我的密码:以数组为参数的Java和Javascript绑定函数,javascript,java,scriptengine,Javascript,Java,Scriptengine,我正在努力做到以下几点。 Java应用程序应该通过ScriptEngineManager/ScriptEngine运行javascript,并且javascript应该能够调用Java应用程序中的函数。只要只传递一个简单的变量,这种方法就非常有效。但我不能让它通过数组。 这是我的密码: private static class test implements Function<Integer[], Integer[]> { @Override public Integ
private static class test implements Function<Integer[], Integer[]> {
@Override
public Integer[] apply(Integer[] msg) {
for(int i = 0; i < msg.length; i++) System.out.println(msg[i]);
Integer[] a = {1, 2, 3};
return a;
}
}
public static void main(String[] args) throws ScriptException {
String ps = "var e = [0x04, 0x05, 0x06]; var a = send(e); for(i in a) print(i);";
ScriptEngineManager sm = new ScriptEngineManager();
ScriptEngine eng = sm.getEngineByName("JavaScript");
Bindings mbind = eng.createBindings();
mbind.put("send", new test());
eng.setBindings(mbind, ScriptContext.ENGINE_SCOPE);
Object t = eng.eval(ps);
}
私有静态类测试实现函数{
@凌驾
公共整数[]应用(整数[]消息){
对于(int i=0;i
我得到一个错误:
线程“main”java.lang.ClassCastException中的异常:jdk.nashorn.api.scripting.ScriptionObjectMirror不能强制转换为[Ljava.lang.Integer;
在scripttest$test.apply处(scripttest.java:1)
在jdk.nashorn.internal.scripts.Script$^eval.:程序(:1)
位于jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)
位于jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
位于jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
位于jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:446)
位于jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:403)
位于jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:399)
位于jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:155)
位于javax.script.AbstractScriptEngine.eval(未知源)
位于scripttest.main(scripttest.java:26)
有人知道如何传递数组吗
谢谢!
关于数组的反射在Java中有点问题(基本类型和所有垃圾),因此JSR-223脚本引擎遇到了问题。我用新的GraalVM尝试了相同的代码,但遇到了相同的问题-引擎放弃了寻找良好的映射,只尝试提交其数组值的本机表示形式(Nashorn使用
ScriptObjectMirror
,而GraalVM使用PolyglotMap
)
如果希望宿主函数看起来像是在接受“真实数组”(来宾数组的实现),则宿主函数需要接受底层ScriptEngine
的内部实现,并学习如何对其进行操作。根据和,您应该能够使用obj.to(int[].class)
从代理对象提取内部整数数组的方法
这种方法的主要缺点是,宿主函数必须支持您可能想要支持的每个特定ScriptEngine
s的每个特定内部表示
由于当前的JDK中不推荐使用Nashorn Javascript引擎,因此您可能也希望支持GraalVM,在这种情况下,您的实现可能会如下所示:
private static class test implements Function<Object, Integer[]> {
@Override
public Integer[] apply(Object inp) {
int[] msg;
if (inp instanceof ScriptObjectMirror)
msg = ((ScriptObjectMirror)inp).to(int[].class);
else if (inp instanceof AbstractMap)
msg = Value.asValue(inp).as(int[].class);
else
return null;
for (int i = 0; i < msg.length; i++)
System.out.println(msg[i]);
Integer[] a = { 1, 2, 3 };
return a;
}
}
私有静态类测试实现函数{
@凌驾
公共整数[]应用(对象inp){
int[]msg;
if(ScriptObjectMirror的inp实例)
msg=((ScriptObjectMirror)inp.to(int[].class);
else if(抽象映射的inp实例)
msg=Value.asValue(inp).as(int[].class);
其他的
返回null;
对于(int i=0;i
请注意,当您的Javascript试图打印结果时,它实际上会在a
的字段上迭代,而不是(…in…)的成员是一种对对象字段进行迭代的语法,因此如果a
确实是一个由3个成员组成的数组,那么无论数组的内容如何,输出都将是0\n1\n2\n
。数组迭代的Javascript语法是for(…of…)
.BTW,关于其中的AbstractMap
内容,不幸的是,无法使用instanceof
检测GraalVM多语言引擎内部类型,因为它们都不是公共类。在只支持GraalVM的实现中,我猜您应该只使用Value.asValue()
无论您得到什么输入,然后使用Value
的API从中获取,但我非常确定Value
不会喜欢Nashorn的代理对象。