Могу ли я насильно устранить перегруженные методы, называемые 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);");
}

С версией доставки Rhino с 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[] в первую очередь заключается в том, что предыдущая версия Rhino не будет автоматически преобразовывать массивы в List, но она преобразует их в Object[].

Если это был личный проект, я просто удалю перегрузку Object[]. Проблема в том, что это общедоступный API, и кто-то может позвонить кому-то прямо сейчас. Я все равно хотел бы перейти на Java 7, но я бы хотел избежать опроса пользователей JavaScript или людей, использующих версию массива метода.

Есть ли способ скрыть перегруженные методы Object[] из Rhino, в то время как другие все равно смогут их вызвать?

Ответ 1

Хотя это не очень элегантно, есть способ специально вызвать один перегруженный Java-метод. Он определен в последнем разделе Java-метода перегрузки и LiveConnect 3. В основном вы используете всю подпись метода, который хотите вызвать, поскольку он отображается в сообщении об ошибке, используя квадратную скобку. В вашем случае должно работать следующее:

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

Немного досадно, что изменение, которое мы сделали с помощью массивов JavaScript, реализующих java.util.List, разбивает существующий код. Возможно, было бы лучше просто выбрать один, если есть несколько методов сопоставления.