Должен ли javac найти методы вне анонимного класса с тем же именем? - PullRequest
4 голосов
/ 31 октября 2008

Этот вопрос является продолжением: Почему я не могу вызвать метод вне анонимного класса с тем же именем

На этот предыдущий вопрос ответ , почему , но теперь я хочу знать, должен ли javac найти прогон (int bar)? (См. Предыдущий вопрос, чтобы узнать, почему run (42) не работает)

Если это не так, это из-за спецификации? Это производит неоднозначный код? Моя точка зрения, я думаю, что это ошибка. В то время как предыдущий вопрос объяснял, почему этот код не компилируется, я считаю, что он должен компилироваться, если javac искал выше в дереве, если ему не удалось найти соответствие на текущем уровне. IE. Если this.run () не совпадает, он должен автоматически проверить NotApplicable.this для метода run.

Также обратите внимание, что foo (int bar) правильно найден. Если вы указываете причину, по которой run (int bar) не должен быть найден, он также должен объяснить, почему foo (int bar) найден.

public class NotApplicable {

    public NotApplicable() {
        new Runnable() {
            public void run() {

                // this works just fine, it automatically used NotApplicable.this when it couldn't find this.foo
                foo(42);

                // this fails to compile, javac find this.run(), and it does not match
                run(42);

                // to force javac to find run(int bar) you must use the following
                //NotApplicable.this.run(42);
            }
        };
    }

    private void run(int bar) {
    }

    public void foo(int bar) {
    }
}

Ответы [ 3 ]

4 голосов
/ 31 октября 2008

Такое поведение javac соответствует спецификации. См. §15.12 Выражения вызова метода в Спецификации языка Java, в частности, параграф в разделе «Шаг 1 времени компиляции», объясняющий значение неквалифицированного вызова метода:

Если Идентификатор появляется в области видимости (§6.3) видимого объявления метода с этим именем, то должно быть вложение декларации типа, членом которого является этот метод. Пусть T будет самым внутренним объявлением типа. Класс или интерфейс для поиска - T.

Другими словами, неквалифицированный метод name ищется во всех входящих в него областях, и самое внутреннее «объявление типа» (которое означает либо объявление класса, либо объявление интерфейса), в котором найдено имя, тот, который будет искать всю подпись (в «Шаге времени компиляции 2»).

1 голос
/ 31 октября 2008

Попробуйте

NotApplicable.this.run(42);

вместо.

1 голос
/ 31 октября 2008

Для меня это звучит как рецепт двусмысленности и хрупкости - как только новый метод добавляется в ваш базовый класс (хорошо, не очень вероятно для интерфейса ...), смысл вашего кода полностью меняется.

Анонимные классы уже довольно уродливы - когда я говорю об этом, я совсем не беспокоюсь.

...