我可以强制消除 Rhino 调用的重载方法的歧义吗?

发布于 2024-12-17 07:36:04 字数 1278 浏览 1 评论 0原文

进行以下测试:

public static class Scripted {
    public void setThing(List<?> list) {
        System.out.println("Set via list");
    }

    public void setThing(Object[] array) {
        System.out.println("Set array");
    }
}

@Test
public void testScripting() throws Exception {
    ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
    engine.getContext().setAttribute("s", new Scripted(), ScriptContext.ENGINE_SCOPE);
    engine.eval("s.thing = Array(1, 2, 3);");
}

对于 Java 7 附带的 Rhino 版本,如果运行此程序,您将得到如下异常:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor setThing matching JavaScript argument types (object) is ambiguous; candidate constructors are:
    void setThing(java.util.List)
    void setThing(java.lang.Object[]) (<Unknown source>#1) in <Unknown source> at line number 1

The Object[] 重载存在首先是因为以前的版本Rhino 不会自动将数组转换为List,但它会将它们转换为Object[]

如果这是一个个人项目,我将删除 Object[] 重载。问题是这是一个公共 API,现在可能有人调用该方法。我仍然想升级到 Java 7,但我想避免让 JavaScript 用户或使用该方法的数组版本的人感到不安。

有没有办法隐藏 Rhino 中的 Object[] 重载方法,而其他人仍然可以调用它们?

Take the following test:

public static class Scripted {
    public void setThing(List<?> list) {
        System.out.println("Set via list");
    }

    public void setThing(Object[] array) {
        System.out.println("Set array");
    }
}

@Test
public void testScripting() throws Exception {
    ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
    engine.getContext().setAttribute("s", new Scripted(), ScriptContext.ENGINE_SCOPE);
    engine.eval("s.thing = Array(1, 2, 3);");
}

With the version of Rhino shipping with Java 7, if you run this, you will get an exception like this:

javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor setThing matching JavaScript argument types (object) is ambiguous; candidate constructors are:
    void setThing(java.util.List)
    void setThing(java.lang.Object[]) (<Unknown source>#1) in <Unknown source> at line number 1

The Object[] overload existence in the first place is because the previous version of Rhino would not automatically convert arrays to List, but it would convert them to Object[].

If this were a personal project this is where I would just delete the Object[] overload. The problem is that this is a public API and there could be someone calling that method right now. I would still like to upgrade to Java 7 but I would like to avoid upsetting either the JavaScript users or the people using the array version of the method.

Is there a way to hide the Object[] overloaded methods from Rhino while others would still be able to call them?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷你仙 2024-12-24 07:36:05

这是针对重载构造函数的(Java 方法重载和 LiveConnect 3):

new java.lang.String["(char[])"](c)

This is for overloaded constructors (Java Method Overloading and LiveConnect 3):

new java.lang.String["(char[])"](c)
雪若未夕 2024-12-24 07:36:04

虽然不是很优雅,但有一种方法可以专门调用一个重载的 Java 方法。它在 Java 方法重载和 LiveConnect 3 规范的最后一部分中定义。基本上,您可以使用错误消息中显示的要调用的方法的整个签名,并使用方括号表示法。在您的情况下,以下内容应该有效:

s["setThing(java.util.List)"](Array(1, 2, 3));

不幸的是,我们对实现 java.util.List 的 JavaScript 数组所做的更改破坏了现有代码。如果有多种匹配方法,也许只选择一种会更好。

Although it's not very elegant there is a way of specifically calling one overloaded Java method. It is defined in the last section of the Java Method Overloading and LiveConnect 3 spec. Basically you use the whole signature of the method you want to call as it is displayed in the error message, using square brackets notation. In your case the following should work:

s["setThing(java.util.List)"](Array(1, 2, 3));

It's a bit unfortunate that the change we made with JavaScript arrays implementing java.util.List breaks existing code. Maybe it would be better to just pick one in case there are multiple matching methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文