入れ子クラスからのprivateメンバに対するアクセス @ Java
Javaでは、privateなメソッド/フィールドに入れ子クラスがアクセスすることができる。
class Hoge { private int hoge; private void hoge() { } class Piyo { void set(int param) { hoge = param; } int get() { return hoge; } void hoge() { Hoge.this.hoge(); } } }
入れ子クラスはコンパイル後には全く独立したクラスとなっているのはclassファイルを見れば明らかだが、そのあおりで実はバイトコードレベルではprivateメンバに対するアクセスはすべて中継メソッドを通す事になるらしい... 上のコードをコンパイルしてjavapしてみたら次のようになった。(一部省略)
class Hoge extends java.lang.Object{ private int hoge; Hoge(); Code: 0: aload_0 1: invokespecial #3; //Method java/lang/Object."<init>":()V 4: return private void hoge(); Code: 0: return static int access$002(Hoge, int); Code: 0: aload_0 1: iload_1 2: dup_x1 3: putfield #2; //Field hoge:I 6: ireturn static int access$000(Hoge); Code: 0: aload_0 1: getfield #2; //Field hoge:I 4: ireturn static void access$100(Hoge); Code: 0: aload_0 1: invokespecial #1; //Method hoge:()V 4: return }
class Hoge$Piyo extends java.lang.Object{ final Hoge this$0; Hoge$Piyo(Hoge); Code: 0: aload_0 1: aload_1 2: putfield #1; //Field this$0:LHoge; 5: aload_0 6: invokespecial #2; //Method java/lang/Object."<init>":()V 9: return void set(int); Code: 0: aload_0 1: getfield #1; //Field this$0:LHoge; 4: iload_1 5: invokestatic #3; //Method Hoge.access$002:(LHoge;I)I 8: pop 9: return int get(); Code: 0: aload_0 1: getfield #1; //Field this$0:LHoge; 4: invokestatic #4; //Method Hoge.access$000:(LHoge;)I 7: ireturn void hoge(); Code: 0: aload_0 1: getfield #1; //Field this$0:LHoge; 4: invokestatic #5; //Method Hoge.access$100:(LHoge;)V 7: return }