当前位置: 首页 > 知识库问答 >
问题:

Java和Javascript绑定函数,数组为参数

邓赤岩
2023-03-14

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

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);
}

我得到了一个错误:

线程“main”java中出现异常。ClassCastException:jdk。纳肖恩。应用程序编程接口。脚本编写。ScriptObjectMirror不能在jdk.nashorn.internal.scripts.Script$\^eval.:jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:637)在jdk.nashorn.internal.ScriptFunction.invoke(ScriptFunction.java:494)在jdk.nashorn.internal.runtime.ScriptRuntime.apply上强制转换为[Ljava.lang.Integer];在ScriptFunctionData.test$test$test.test$test$test.java:1])(ScriptRuntime.java:393)在jdk。纳肖恩。应用程序编程接口。脚本编写。纳什启动了引擎。jdk的evalImpl(NashornScriptEngine.java:446)。纳肖恩。应用程序编程接口。脚本编写。纳什启动了引擎。jdk的evalImpl(NashornScriptEngine.java:403)。纳肖恩。应用程序编程接口。脚本编写。纳什启动了引擎。jdk的evalImpl(NashornScriptEngine.java:399)。纳肖恩。应用程序编程接口。脚本编写。纳什启动了引擎。eval(NashornScriptEngine.java:155)在javax上。剧本抽象脚本引擎。脚本测试中的eval(未知源)。main(scripttest.java:26)

有人知道如何传递数组吗?

谢谢当做

共有1个答案

任飞龙
2023-03-14

在Java(原始类型,以及所有那些垃圾)中,对数组的反射有点问题,所以JSR-223脚本引擎在使用它们时遇到了麻烦。我在新的GraalVM上尝试了同样的代码,它也遇到了同样的问题——引擎放弃了寻找一个好的映射,只是试图提交数组值的本地表示(Nashorn使用ScriptObjectMirror,而GraalVM使用PolyglotMap)。

如果希望宿主函数看起来像是在接受“真实数组”(来宾数组的实现),则宿主函数需要接受底层的ScriptEngine的内部实现,并学习如何对其进行操作。根据这个答案和ScriptObjectMirror API文档,您应该能够使用obj。to(int[].class)方法从代理对象提取内部整数数组。

这种方法的主要缺点是,宿主函数必须支持您可能想要支持的每个特定ScriptEngines的每个特定内部表示。

由于当前的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;
    }
}
 类似资料:
  • 问题内容: 我正在尝试绑定准备好的语句参数,该参数是“多维” PostgreSQL数组。这是一个数组示例(列类型为): 如何使用预处理语句绑定类似的值?我试过了: 它没有用: 无法将java.lang.String的实例强制转换为Types.ARRAY 有任何想法吗? 问题答案: 尝试这样的事情(未经测试): 链接: JDBC中的Postgres和多维数组 将数组从Java传递到Postgres

  • 问题内容: 我有一个功能可以做到这一点: 哪个发送到我的数据库类,它执行以下操作: 问题是这不起作用。 我希望做的是获取列表,并在后面列出它们,以使查询类似于: 但是很明显,我走错了路。 有没有办法使数组…按原样转换为要在查询阶段打印出来的列表? 问题答案: call_user_func_array “使用参数数组调用回调” 应该做的工作 更新 :您还必须更改您的params数组: 如预期的那样,

  • 问题内容: 我正在尝试将数组作为IN变量传递给for。我怎样才能做到这一点? 我无法让它为我的一生工作。有什么想法吗?上面的代码只是一个示例。 问题答案: 在这种情况下,这样做是不合适的。您正在构造实际的SQL(这就是逗号和引号),并将其作为参数传递。它基本上以评估那里是全部。 同样,这是关于引号的一个好电话。MySQL使用单引号。 您将需要仅使用字符串连接来构建SQL,或者使用多个参数。 编辑

  • 参数绑定是把当前请求的变量作为操作方法(也包括架构方法)的参数直接传入,参数绑定并不区分请求类型。 参数绑定传入的值会经过全局过滤,如果你有额外的过滤需求可以在操作方法中单独处理。 按名称绑定 参数绑定方式默认是按照变量名进行绑定,例如,我们给Blog控制器定义了两个操作方法read和archive方法,由于read操作需要指定一个id参数,archive方法需要指定年份(year)和月份(mon

  • 问题内容: 我想使用数组作为参数调用一个函数: 有路过的内容的一种更好的方式进入? 问题答案: const args = [‘p0’, ‘p1’, ‘p2’]; call_me.apply(this, args); 请参阅MDN文档。 如果环境支持ECMAScript6,则可以改用传播参数:

  • 当将对象方法作为回调进行传递,例如传递给 setTimeout,这儿会存在一个常见的问题:“丢失 this”。 在本章中,我们会学习如何去解决这个问题。 丢失 “this” 我们已经看到了丢失 this 的例子。一旦方法被传递到与对象分开的某个地方 —— this 就丢失。 下面是使用 setTimeout 时 this 是如何丢失的: let user = { firstName: "Joh