(編集:コメントのいくつかに答えることを答えに拡大)
は、コンパイラが内部クラスを取り、トップレベルのクラスにそれらを回します。プライベートメソッドはインナークラスでのみ使用可能であるため、コンパイラはパッケージレベルのアクセス権を持つ新しい「合成」メソッドを追加して、トップレベルのクラスがアクセスできるようにする必要があります。このような
何か($ものは、コンパイラによって追加されます):
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レベルでは内部クラスのようなものはありません)。コンパイラはまた、新しい "転送"メソッドを生成する必要があります。これらは、パッケージレベル(公開されていない)で作成され、同じパッケージ内のクラスのみがアクセスできるようにします。コンパイラはまた、生成された "転送"メソッドに対するプライベートメソッドへのメソッド呼び出しを更新しました。
コンパイラがメソッドを「パッケージ」(public、private、およびprotectedの不在)として宣言しているのを避けることができます。その欠点は、パッケージ内のどのクラスでもメソッドを呼び出せることです。
そのため、メソッドをprivateに宣言し、コンパイラはエラーを生成せずにpublicにしますか? – cbrulak
まあパブリックではありませんパッケージです。そして、はい、そうです。これは、VMに内部クラスに関する知識がないためです。コンパイラは、VMを特別な処理を行う代わりに、すべての作業を行います。 – TofuBeer
パッケージは内部クラスを含むクラスですか? – cbrulak