¿Qué parte de JLS dijo que las clases anónimas no pueden tener clases miembro públicas / protegidas / privadas?
Considera este pedazo de código:
public class TopLevelClass {
Cloneable c = new Cloneable() {
private int privateField;
private void privateMethod() {};
};
}
Hay una clase anónima que tiene unaprivate
campo miembro y unprivate
método miembro Se ha compilado con éxito.
Entonces considera este:
public class TopLevelClass {
Cloneable c = new Cloneable() {
private class PrivateInnerClass {}
};
}
Hay una clase anónima que tiene unaprivate
clase miembro Sin embargo...
error: modifier private not allowed here
Eclipse dijo:Illegal modifier for the local class PrivateInnerClass; only abstract or final is permitted
¿Realmente clase local?¿Qué?Por qué las clases anónimas no pueden tenerpublic
, protected
oprivate
(denominado en lo sucesivothose
) clases de miembros mientras pueden tenerthose
campos y métodos de miembro? Confundido, miré en JLS. Debido a lo que Eclipse dijo, miréclases locales primero:
A clase local es una clase anidada (§8) que no es miembro de ninguna clase y que tiene un nombre (§6.2, §6.7).
Es un error en tiempo de compilación si una declaración de clase local contiene alguno de los modificadores de accesopublic
, protected
oprivate
(§6.6), o el modificadorstatic
(§8.1.1).
Así que la clase local no puede tenerthose
modificadores PeroPrivateInnerClass
es un miembro del anonimoCloneable
, por lo que no es una clase local y todavía puede tenerthose
modificadores
Entonces miré enmodificadores de clase:
8.1.1. Modificadores de claseEl modificador de accesopublic
(§6.6) pertenece solo a las clases de nivel superior (§7.6) y para las clases miembro (§8.5), no a clases locales (§14.3) o clases anónimas (§15.9.5).
Los modificadores de accesoprotected
yprivate
(§6.6) pertenecen solo a clases miembro dentro de una clase que encierra directamente o una declaración de enumeración (§8.5).
PeroPrivateInnerClass
es una clase miembro, y está dentro de una clase que contiene directamente, el anónimoCloneable
, por lo que todavía puede tenerthose
Los modificadores de la teoría. También busqué en otras partes, pero todavía no pude encontrar disposiciones relevantes.
Entonces, ¿qué parte de la especificación del lenguaje Java dijo que una clase miembro de una clase anónima no puede tenerthose
modificador?
Nota adicional 1: Alguna respuesta argumentó sobre las clases miembros y las clases locales, así que hice una prueba que puede concluir que (a menos que los modificadores importen):
El anónimoCloneable
esni una clase miembro ni una clase local.losPrivateInnerClass
es una clase miembro, perono es una clase local.El siguiente es mi código de prueba:
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("TopLevelClassHay una clase anónima que tiene unaPrivateInnerClass");
System.out.println(c1.isMemberClass()); // false
System.out.println(c1.isLocalClass()); // false
System.out.println(c2.isMemberClass()); // true
System.out.println(c2.isLocalClass()); // false
}
}
Nota adicional 2: Revisar la declaración de una clase normal (JLS §8.1):
NormalClassDeclaration: ClassModifiersopt class Identifier TypeParametersopt Superopt Interfacesopt ClassBody
En mi entendimiento, cuando elIdentifier
la clase es una clase xxx que§8.1.1 declarado es restringir el modificador deIdentifier
, no los modificadores en otras declaraciones enClassBody
deIdentifier
. De lo contrario, las clases anónimas ni siquiera pueden tenerthose
Campos y métodos miembros.
Cualquier respuesta, especialmente si está en desacuerdo con la Nota Extra 2, debe indicar por quéthose
campos y métodos de miembros están permitidos.
Nota adicional 3: Si crees que no hay tal parte de JLS,Todavía tendrá que dar un documento confiable para explicar por quéthose
clases de miembros están prohibidos y por quéthose
campos y métodos de miembros están permitidos.