Должен ли javac находить методы вне анонимного класса с тем же именем?

StackOverflow https://stackoverflow.com/questions/254260

Вопрос

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

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

Если этого не должно быть, связано ли это со спецификацией?Создает ли это неоднозначный код?Я хочу сказать, что я думаю, что это ошибка.Хотя в предыдущем вопросе объяснялось, почему этот код не компилируется, я считаю, что он должен компилироваться, если javac выполнял поиск выше по дереву, если ему не удается найти соответствие на текущем уровне.Т.е.Если this.run() не соответствует, он должен автоматически проверить NotApplicable.это для метода 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) {
    }
}
Это было полезно?

Решение

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

  

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

Другими словами, поиск неквалифицированного метода name ищется во всех входящих в него областях, и в самой внутренней " декларации типа " (что означает либо класс, либо объявление интерфейса), в котором найдено имя - это то, которое будет искать всю сигнатуру (в " Compile Time Step 2 ").

Другие советы

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

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

Попробуй

NotApplicable.this.run(42);

вместо этого.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top