从内部类引用封闭实例

4

这只是一个知识/好奇心问题。

在Java中工作了几年后,这才让我意识到。

class Foo {

   class Bar{

      Foo.this.doSomething();

   }

}

当我看到Foo.this时,我会认为它是一个静态引用,但实际上不是这样。
我知道这是Java规范的一部分,但使用<Class>.this时究竟发生了什么?
这是其中的一个"它就是这个样子"的事情。

@noob。请不要删除Android标签。我只使用Java编码,因为我创建Android应用程序。这个问题对Android开发人员也具有广泛的相关性。 - Simon
1
首先,Bhesh Gurung是删除了Android标签的人,而不是noob。您使用Android的事实与标记无关。如果我使用Java编程创建Windows应用程序,我也可以轻松地将此问题标记为Windows。您的问题没有使用任何与Android相关的功能,因此不需要Android标签。我已经克制自己不去撤销您的编辑,但这仅仅是因为害怕无意义的编辑战争。 - Brian
@Brian。嗯,这都有点儿荒谬,但如果大多数Android开发人员也订阅了Java标签,我可能会同意你的看法。由于他们没有这样做,而且Android开发人员是所有Java开发人员中非常重要的一组,因此我不同意。感谢您留下编辑。 - Simon
@Brian。抱歉,顺便说一句,我太蠢了没有检查编辑历史记录,并向新手道歉。 - Simon
@Simon:我建议删除android标签。目前情况下,它会给人错误的印象,认为这个Java问题仅适用于Android,因此在查找不包括Android特定问题的一般Java问题时,它会被过滤掉。想要了解一般Java知识的Android开发者可以自由地搜索java标签。 - O. R. Mapper
这绝对不是特定于Android的问题,因此必须删除Android标签。 - Dorian Gray
1个回答

9
我知道这是Java规范的一部分,但当你使用.this时到底发生了什么呢?
它只是引用了Bar中的一个“隐藏”字段。通过反编译,你可以最容易地看到这一点。你会看到有一个Bar构造函数,它接受一个对Foo实例的引用。该引用存储在一个字段中,然后当你使用Foo.this时,它只是访问该字段。因此,假设你将Foo.this.doSomething()放入一个someMethod调用中,你的代码类似于:
class Foo {

   static class Bar {
      private final Foo $foo;

      Bar(Foo foo) {
          this.$foo = foo;
      }    

      public void someMethod() {
          $foo.doSomething();
      }
   }
}

谢谢Jon,我以前从来不知道这些。像这样清晰地阐述一切真是太好了 ;) - Simon
@JonSkeet 不错的答案,但如果这是反编译后的样子,当内部类有参数化构造函数时它是如何工作的呢? - Mark W
@MarkW:为什么不试一下呢? :) (它只会向您编写的列表中添加一个额外的参数...) - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接