我能否强制消除Rhino调用的重载方法的歧义?

10

请参加以下测试:

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

首先,首选使用List而不是Object[]的原因是,Rhino的早期版本不会自动将数组转换为List,但它会将它们转换为Object[]

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

是否有一种方法可以隐藏Rhino中的Object[]重载方法,同时其他人仍然能够调用它们?

2个回答

11

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

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

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


我同意...如果它只是像这样调用List而不会失败,那就更好了。但是Java 7在我们的应用程序中破坏了很多其他东西,这只是其中之一(其他问题,如Locale更改,都已解决)。 - Hakanai

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接