謎のaccess$0メソッドの話。
謎のメソッドがコンパイラによって生成されているのだけど、
何故そのメソッドが作られるのか、どの様な役割を持っているのか、
全く持って意味が分からないので、誰か教えてクダサシ。
解決しるました。
まず、こんなコードを書くます。
public class Deny { public void execute() { dddd(); } public void dddd() { for (Method m : getClass().getDeclaredMethods()) { System.out.println(m.toString()); } System.setProperty("bbb", getClass().getName()); String s = System.getProperty("bbb"); System.out.println(s); new Throwable().printStackTrace(System.out); } } public class Ok extends Deny { @Override public void execute() { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { Ok.super.execute(); return null; } }); } public void execute2() { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { new Hoge().hoge(Ok.this); return null; } }); } } public class Hoge { public void hoge(final Ok ok) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { ok.dddd(); return null; } }); } }
Ok.classに、ソースコード上では存在しない、access$0と言う謎メソッドが生成されているます。
そやつだけ抜粋すると、こんな感じ。
static void access$0(aa.bb.cc.Ok); Code: 0: aload_0 1: invokespecial #31; //Method aa/bb/cc/Deny.execute:()V 4: return
何というか、ほぼ全く何もしていないstaticメソッドでつ。
何故、コイツが必要になるのか良く分かりません。
僕が知りたいのは、以下の通り。
知っている方がいたらぜひ教えてクダサシ。
何となくだけど、今分かっているのは、
-java.security.AccessController
- java.security.PrivilegedAction
この辺が関係があるっぽい…?のかな…と言う事だけでつ。
不思議。
インナークラスとsuperと言うキーワードがセットになると、出来るっぽい感じ。
全部をjavapしてみたのは、以下。
ちなみに、eclipseのJDTがコンパイルした.classファイルをjavapしているます。
Compiled from "Deny.java" public class aa.bb.cc.Deny extends java.lang.Object{ public aa.bb.cc.Deny(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return public void execute(); Code: 0: aload_0 1: invokevirtual #15; //Method dddd:()V 4: return public void dddd(); Code: 0: aload_0 1: invokevirtual #18; //Method java/lang/Object.getClass:()Ljava/lang/Class; 4: invokevirtual #22; //Method java/lang/Class.getDeclaredMethods:()[Ljava/lang/reflect/Method; 7: dup 8: astore 4 10: arraylength 11: istore_3 12: iconst_0 13: istore_2 14: goto 35 17: aload 4 19: iload_2 20: aaload 21: astore_1 22: getstatic #28; //Field java/lang/System.out:Ljava/io/PrintStream; 25: aload_1 26: invokevirtual #34; //Method java/lang/reflect/Method.toString:()Ljava/lang/String; 29: invokevirtual #40; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 32: iinc 2, 1 35: iload_2 36: iload_3 37: if_icmplt 17 40: ldc #46; //String bbb 42: aload_0 43: invokevirtual #18; //Method java/lang/Object.getClass:()Ljava/lang/Class; 46: invokevirtual #48; //Method java/lang/Class.getName:()Ljava/lang/String; 49: invokestatic #51; //Method java/lang/System.setProperty:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; 52: pop 53: ldc #46; //String bbb 55: invokestatic #55; //Method java/lang/System.getProperty:(Ljava/lang/String;)Ljava/lang/String; 58: astore_1 59: getstatic #28; //Field java/lang/System.out:Ljava/io/PrintStream; 62: aload_1 63: invokevirtual #40; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 66: new #59; //class java/lang/Throwable 69: dup 70: invokespecial #61; //Method java/lang/Throwable."<init>":()V 73: getstatic #28; //Field java/lang/System.out:Ljava/io/PrintStream; 76: invokevirtual #62; //Method java/lang/Throwable.printStackTrace:(Ljava/io/PrintStream;)V 79: return } Compiled from "Ok.java" public class aa.bb.cc.Ok extends aa.bb.cc.Deny{ public aa.bb.cc.Ok(); Code: 0: aload_0 1: invokespecial #8; //Method aa/bb/cc/Deny."<init>":()V 4: return public void execute(); Code: 0: new #15; //class aa/bb/cc/Ok$1 3: dup 4: aload_0 5: invokespecial #17; //Method aa/bb/cc/Ok$1."<init>":(Laa/bb/cc/Ok;)V 8: invokestatic #20; //Method java/security/AccessController.doPrivileged:(Ljava/security/PrivilegedAction;)Ljava/lang/Object; 11: pop 12: return public void execute2(); Code: 0: new #27; //class aa/bb/cc/Ok$2 3: dup 4: aload_0 5: invokespecial #29; //Method aa/bb/cc/Ok$2."<init>":(Laa/bb/cc/Ok;)V 8: invokestatic #20; //Method java/security/AccessController.doPrivileged:(Ljava/security/PrivilegedAction;)Ljava/lang/Object; 11: pop 12: return static void access$0(aa.bb.cc.Ok); Code: 0: aload_0 1: invokespecial #31; //Method aa/bb/cc/Deny.execute:()V 4: return } Compiled from "Ok.java" class aa.bb.cc.Ok$1 extends java.lang.Object implements java.security.PrivilegedAction{ final aa.bb.cc.Ok this$0; aa.bb.cc.Ok$1(aa.bb.cc.Ok); Code: 0: aload_0 1: aload_1 2: putfield #12; //Field this$0:Laa/bb/cc/Ok; 5: aload_0 6: invokespecial #14; //Method java/lang/Object."<init>":()V 9: return public java.lang.Object run(); Code: 0: aload_0 1: getfield #12; //Field this$0:Laa/bb/cc/Ok; 4: invokestatic #23; //Method aa/bb/cc/Ok.access$0:(Laa/bb/cc/Ok;)V 7: aconst_null 8: areturn } Compiled from "Ok.java" class aa.bb.cc.Ok$2 extends java.lang.Object implements java.security.PrivilegedAction{ final aa.bb.cc.Ok this$0; aa.bb.cc.Ok$2(aa.bb.cc.Ok); Code: 0: aload_0 1: aload_1 2: putfield #12; //Field this$0:Laa/bb/cc/Ok; 5: aload_0 6: invokespecial #14; //Method java/lang/Object."<init>":()V 9: return public java.lang.Object run(); Code: 0: new #23; //class aa/bb/cc/Hoge 3: dup 4: invokespecial #25; //Method aa/bb/cc/Hoge."<init>":()V 7: aload_0 8: getfield #12; //Field this$0:Laa/bb/cc/Ok; 11: invokevirtual #26; //Method aa/bb/cc/Hoge.hoge:(Laa/bb/cc/Ok;)V 14: aconst_null 15: areturn } Compiled from "Hoge.java" public class aa.bb.cc.Hoge extends java.lang.Object{ public aa.bb.cc.Hoge(); Code: 0: aload_0 1: invokespecial #8; //Method java/lang/Object."<init>":()V 4: return public void hoge(aa.bb.cc.Ok); Code: 0: new #16; //class aa/bb/cc/Hoge$1 3: dup 4: aload_0 5: aload_1 6: invokespecial #18; //Method aa/bb/cc/Hoge$1."<init>":(Laa/bb/cc/Hoge;Laa/bb/cc/Ok;)V 9: invokestatic #21; //Method java/security/AccessController.doPrivileged:(Ljava/security/PrivilegedAction;)Ljava/lang/Object; 12: pop 13: return } Compiled from "Hoge.java" class aa.bb.cc.Hoge$1 extends java.lang.Object implements java.security.PrivilegedAction{ final aa.bb.cc.Hoge this$0; aa.bb.cc.Hoge$1(aa.bb.cc.Hoge, aa.bb.cc.Ok); Code: 0: aload_0 1: aload_1 2: putfield #14; //Field this$0:Laa/bb/cc/Hoge; 5: aload_0 6: aload_2 7: putfield #16; //Field val$ok:Laa/bb/cc/Ok; 10: aload_0 11: invokespecial #18; //Method java/lang/Object."<init>":()V 14: return public java.lang.Object run(); Code: 0: aload_0 1: getfield #16; //Field val$ok:Laa/bb/cc/Ok; 4: invokevirtual #27; //Method aa/bb/cc/Ok.dddd:()V 7: aconst_null 8: areturn }
JDK1.6に付属しているjavacでコンパイルすると、微妙に違いがあったりします。
こんな感じ。
Compiled from "Ok.java" public class aa.bb.cc.Ok extends aa.bb.cc.Deny{ public aa.bb.cc.Ok(); Code: 0: aload_0 1: invokespecial #2; //Method aa/bb/cc/Deny."<init>":()V 4: return public void execute(); Code: 0: new #3; //class aa/bb/cc/Ok$1 3: dup 4: aload_0 5: invokespecial #4; //Method aa/bb/cc/Ok$1."<init>":(Laa/bb/cc/Ok;)V 8: invokestatic #5; //Method java/security/AccessController.doPrivileged:(Ljava/security/PrivilegedAction;)Ljava/lang/Object; 11: pop 12: return public void execute2(); Code: 0: new #6; //class aa/bb/cc/Ok$2 3: dup 4: aload_0 5: invokespecial #7; //Method aa/bb/cc/Ok$2."<init>":(Laa/bb/cc/Ok;)V 8: invokestatic #5; //Method java/security/AccessController.doPrivileged:(Ljava/security/PrivilegedAction;)Ljava/lang/Object; 11: pop 12: return static void access$001(aa.bb.cc.Ok); Code: 0: aload_0 1: invokespecial #1; //Method aa/bb/cc/Deny.execute:()V 4: return }
微妙にaccess$の後の数字の採番ルールが違いまつね。