java – 为什么匿名类即使不需要也会捕获“this”?

前端之家收集整理的这篇文章主要介绍了java – 为什么匿名类即使不需要也会捕获“this”?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
鉴于此代码
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).

JLS 8.1.3.

“即使他们不需要”,也不例外.

猜你在找的Java相关文章