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

时间:2011-11-21 06:11:22

标签: java overloading rhino

进行以下测试:

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

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

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

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

2 个答案:

答案 0 :(得分:10)

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

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

我们使用实现java.util.List的JavaScript数组所做的更改会破坏现有代码,这有点不幸。也许最好只选择一个,以防有多种匹配方法。

答案 1 :(得分:0)

这适用于重载的构造函数(Java Method Overloading and LiveConnect 3):

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