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

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

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

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

Также обратите внимание, что 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) {
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
331
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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

Хорошо, тогда почему javac разрешено находить foo (int bar)? Рецепт тот же.

Pyrolistical 31.10.2008 20:20

Это правда. Ба, это все ужасный беспорядок. Дайте мне правильное закрытие :)

Jon Skeet 31.10.2008 20:34
Ответ принят как подходящий

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

If the Identifier appears within the scope (§6.3) of a visible method declaration with that name, then there must be an enclosing type declaration of which that method is a member. Let T be the innermost such type declaration. The class or interface to search is T.

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

Спасибо, я думаю, что понимаю спецификацию. Теперь я могу утверждать, что это плохая спецификация и ее следует изменить. Шаг 1 времени компиляции должен включать в себя включающий класс анонимного класса.

Pyrolistical 31.10.2008 20:44

Пытаться

NotApplicable.this.run(42);

вместо.

Обратите внимание, что в то время, когда я писал этот ответ, комментарий с тем же фрагментом кода в нем не присутствовал в вопросе.

nsayer 08.11.2008 02:15

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