Во-первых, эта проблема не указана c для перечислений. Это применимо к любому внутреннему классу. Я реорганизовал ваш пример для удаления enum, который демонстрирует ту же проблему как с внутренним классом, так и с анонимным внутренним классом.
Пример 6.5.7.1-1. Простые имена методов
Следующая программа демонстрирует роль определения области действия при определении того, какой метод вызывать.
class Super {
void f2(String s) {}
void f3(String s) {}
void f3(int i1, int i2) {}
}
class Test {
void f1(int i) {}
void f2(int i) {}
void f3(int i) {}
void m() {
new Super() {
{
f1(0); // OK, resolves to Test.f1(int)
f2(0); // compile-time error
f3(0); // compile-time error
}
};
}
}
Для вызова f1(0)
только один метод с именем f1 находится в объем. Это метод Test.f1(int)
, объявление которого находится в области видимости всего тела Test, включая объявление анонимного класса. §15.12.1 выбирает поиск в классе Test, поскольку объявление анонимного класса не имеет члена с именем f1
. В конце концов, Test.f1(int)
разрешается.
Для вызова f2(0)
в области действия находятся два метода с именем f2
. Во-первых, объявление метода Super.f2(String)
находится в области действия объявления анонимного класса. Во-вторых, объявление метода Test.f2(int)
находится в области видимости всего тела Test, включая объявление анонимного класса. (Обратите внимание, что ни одно объявление не затеняет другое, потому что в точке, где каждое из них объявлено, другое не входит в область действия.) §15.12.1 выбирает поиск в классе Super, потому что в нем есть член с именем f2
. Однако Super.f2(String)
не применимо к f2(0)
, поэтому возникает ошибка времени компиляции. Обратите внимание, что класс Test
не ищется.
Для вызова f3(0)
три области с именем f3
находятся в области видимости. Во-первых, во-вторых, объявления методов Super.f3(String)
и Super.f3(int,int)
находятся в области действия объявления анонимного класса. В-третьих, объявление метода Test.f3(int)
находится в области видимости всего тела Test, включая объявление анонимного класса. §15.12.1 выбирает поиск в классе Super
, поскольку в нем есть член с именем f3
. Однако Super.f3(String)
и Super.f3(int,int)
не применимы к f3(0)
, поэтому возникает ошибка времени компиляции. Обратите внимание, что класс Test
не ищется.
Выбор для поиска иерархии суперкласса вложенного класса до того, как лексически заключенную область видимости называют "правилом гребня" ( §15.12.1 ).