(编辑:扩大答案回答一些评论)
编译器接受内部类并将其转换为顶级类。由于私有方法仅适用于内部类,编译器必须添加具有包级别访问权限的新“合成”方法,以便顶层类可以访问它。
这样的东西($编译器添加的):
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();
}
}
非静态类是相同的,但是它们添加了对外部类的引用,以便可以调用这些方法。
Java这样做的原因是他们不想要更改VM来支持内部类,所以所有这些更改都必须在编译器级别。
编译器接收内部类并将其转换为顶级类(因此,在VM级别,没有内部类)。编译器也必须生成新的“转发”方法。它们是在包级别(不是公共的)制造的,以确保只有同一个包中的类可以访问它们。编译器还将方法调用更新到私有方法到生成的“转发”方法。
您可以避免编译器生成方法,我将方法声明为“package”(缺少public,private和protected)。缺点是包中的任何类都可以调用方法。