Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
以数组为参数的Java和Javascript绑定函数_Javascript_Java_Scriptengine - Fatal编程技术网

以数组为参数的Java和Javascript绑定函数

以数组为参数的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

我正在努力做到以下几点。 Java应用程序应该通过ScriptEngineManager/ScriptEngine运行javascript,并且javascript应该能够调用Java应用程序中的函数。只要只传递一个简单的变量,这种方法就非常有效。但我不能让它通过数组。 这是我的密码:

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的代理对象。