入れ子クラスからの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
}