Могу ли я принудительно устранить неоднозначность перегруженных методов, вызываемых Rhino? - PullRequest
10 голосов
/ 21 ноября 2011

Пройдите следующий тест:

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[] отНосорог, в то время как другие все еще смогут позвонить им?

Ответы [ 2 ]

10 голосов
/ 21 ноября 2011

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

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

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

0 голосов
/ 18 мая 2017

Это для перегруженных конструкторов ( Перегрузка метода Java и LiveConnect 3 ):

new java.lang.String["(char[])"](c)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...