2011-11-21 57 views
10

看看下面的测试:我可以强制消除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,如果你运行它,你会得到这样一个例外:

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[]超载存在的第一个地方是因为以前的版本犀牛不会自动将数组转换为List,但它转换成Object[]

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

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

回答

10

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

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

这是一个有点可惜,我们用JavaScript数组实现java.util.List中所做的改动破坏现有的代码。如果有多种匹配方法,也许只选一个会更好。

+0

我同意......它会更好,如果它只是叫列出一个不会失败这样的。但是Java 7在我们的应用程序中已经打破了其他一些东西,这只是其中的一个(其他的,像Locale更改,都已经解决了。) – Trejkaz

相关问题