(Edit: ampliado de la respuesta a responder algunas de las observaciones)
El compilador toma las clases interiores y los convierte en clases de nivel superior. Como los métodos privados solo están disponibles para la clase interna, el compilador tiene que agregar nuevos métodos "sintéticos" que tengan acceso a nivel de paquete para que las clases de nivel superior tengan acceso a él.
Algo como esto (los $ aplicaciones que se agregan por el compilador):
class A
{
private void f()
{
final B b;
b = new B();
// call changed by the compiler
b.$g();
}
// method generated by the compiler - visible by classes in the same package
void $f()
{
f();
}
}
class B
{
private void g()
{
final A a;
a = new A();
// call changed by the compiler
a.$f();
}
// method generated by the compiler - visible by classes in the same package
void $g()
{
g();
}
}
clases no estáticos son los mismos, pero tienen la adición de una referencia a la clase exterior, de manera que los métodos pueden ser llamado sobre eso.
La razón por la que Java lo hace de esta manera es que no querían requerir cambios de máquina virtual para admitir clases internas, por lo que todos los cambios tenían que ser al nivel del compilador.
El compilador toma la clase interna y la convierte en una clase de nivel superior (por lo tanto, en el nivel VM no existe una clase interna). El compilador también debe generar los nuevos métodos de "reenvío". Están hechos a nivel de paquete (no público) para garantizar que solo las clases en el mismo paquete puedan acceder a ellos. El compilador también actualizó las llamadas de método a los métodos privados a los métodos de "reenvío" generados.
Puede evitar que el compilador genere el método al declarar los métodos como "paquete" (la ausencia de protección pública, privada y protegida). La desventaja de eso es que cualquier clase en el paquete puede llamar a los métodos.
entonces, declaras un método privado y el compilador lo convierte en público en lugar de generar un error? – cbrulak
bien, no es público, es un paquete. Y, sí, eso es lo que hace. Esto se debe a que la VM no tiene conocimiento de las clases internas ... por lo que el compilador hace todo el trabajo en lugar de hacer que la VM haga cosas especiales. – TofuBeer
paquete que es la clase que contiene la clase interna? – cbrulak