Какая часть JLS сказала, что у анонимных классов не может быть открытых / защищенных / закрытых классов-членов
Рассмотрим этот кусок кода:
public class TopLevelClass {
Cloneable c = new Cloneable() {
private int privateField;
private void privateMethod() {};
};
}
Существует анонимный класс, который имеетprivate
член поля иprivate
член метод. Он был успешно скомпилирован.
Тогда рассмотрим это:
public class TopLevelClass {
Cloneable c = new Cloneable() {
private class PrivateInnerClass {}
};
}
Существует анонимный класс, который имеетprivate
член класса. Тем не мение...
error: modifier private not allowed here
Затмение сказал:Illegal modifier for the local class PrivateInnerClass; only abstract or final is permitted
Действительно местный класс?Какая?Почему анонимные классы не могут иметьpublic
, protected
или жеprivate
(именуемый в дальнейшемthose
) классы участников, пока они могут иметьthose
член поля и методы? Смутившись, я заглянул в JLS. Из-за того, что сказал Eclipse, я посмотрел наместные классы первый:
A местный класс является вложенным классом (§8) который не является членом какого-либо класса и имеет имя (§6.2, §6.7).
Это ошибка времени компиляции, если объявление локального класса содержит какой-либо из модификаторов доступаpublic
, protected
, или жеprivate
(§6.6) или модификаторstatic
(8.1.1).
Так что местный класс не может иметьthose
модификаторы. НоPrivateInnerClass
является член анонимногоCloneable
так что это не местный класс и все еще может иметьthose
модификаторы.
Затем я посмотрел вмодификаторы класса:
8.1.1. Модификаторы классаМодификатор доступаpublic
(§6.6) относится только к классам высшего уровня (§7.6) и для членов классов (§8.5), а не для местных классов (§14.3) или анонимные занятия (§15.9.5).
Модификаторы доступаprotected
а такжеprivate
(§6.6) относятся только к классам-членам в пределах непосредственно включенного класса или объявления enum (§8.5).
НоPrivateInnerClass
является классом-членом, и он находится внутри непосредственно включенного класса, анонимногоCloneable
так что еще можноthose
модификаторы по теории. Я изучал и другие части, но все еще не мог найти соответствующие положения.
Итак, какая часть спецификации языка Java говорит, что класс-член анонимного класса не может иметьthose
модификатор?
Дополнительное примечание 1: В некоторых ответах обсуждались классы-члены и локальные классы, поэтому я сделал тест, который может заключить, что (если модификаторы не имеют значения)
АнонимныйCloneable
являетсяни членский класс, ни локальный класс.PrivateInnerClass
является членом класса, ноне местный класс.Вот мой тестовый код:
public class TopLevelClass {
Cloneable c = new Cloneable() {
class PrivateInnerClass {}
};
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c1 = Class.forName("TopLevelClass$1");
Class<?> c2 = Class.forName("TopLevelClassСуществует анонимный класс, который имеетPrivateInnerClass");
System.out.println(c1.isMemberClass()); // false
System.out.println(c1.isLocalClass()); // false
System.out.println(c2.isMemberClass()); // true
System.out.println(c2.isLocalClass()); // false
}
}
Дополнительное примечание 2: Просмотрите объявление нормального класса (JLS §8.1):
NormalClassDeclaration: ClassModifiersopt class Identifier TypeParametersopt Superopt Interfacesopt ClassBody
В моем понимании, когдаIdentifier
класс это класс XXX, что8.1.1 заявлено ограничивает модификаторIdentifier
, а не модификаторы в других объявлениях вClassBody
изIdentifier
, В противном случае анонимные классы даже не могут иметьthose
члены поля и методы.
Любой ответ, особенно если он не согласен с Extra Note 2, должен указывать, почемуthose
члены поля и методы разрешены.
Дополнительное примечание 3: Если вы думаете, что нет такой части JLS,вам все еще нужно будет предоставить надежный документ, чтобы объяснить, почемуthose
запрещено посещать занятия и почемуthose
члены поля и методы разрешены.