鉴于此代码:
class Foo {} public class Test { public Foo makeFoo(String p,String q) { return new Foo(){ public void doSomething() { System.out.println(p); } }; } }
当你编译并运行javap -c -p’Test $1.class’时,你得到这个:
Compiled from "Test.java" class Test$1 extends Foo { final java.lang.String val$p; final Test this$0; Test$1(Test,java.lang.String); Code: 0: aload_0 1: aload_1 2: putfield #1 // Field this$0:LTest; 5: aload_0 6: aload_2 7: putfield #2 // Field val$p:Ljava/lang/String; 10: aload_0 11: invokespecial #3 // Method Foo."<init>":()V 14: return public void doSomething(); Code: 0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 3: aload_0 4: getfield #2 // Field val$p:Ljava/lang/String; 7: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 10: return }
当创建匿名类时,变量p被捕获到val $p中(如预期的那样,因为它是必需的),而变量q不是(正如预期的那样,因为它不需要).但是,Test.this被捕获到这个$0,即使它不需要.这是Java规范的强制要求,还是它恰好的工作方式?为什么这样工作?
解决方法
因为它是一个内在的类,因为
An instance i of a direct inner class C of a class or interface O is associated with an instance of O,known as the immediately enclosing instance of i. The immediately enclosing instance of an object,if any,is determined when the object is created (§15.9.2).
“即使他们不需要”,也不例外.