隐式 "this" 在匿名 class 中指的是什么?

What does implicit "this" refer to in an anonymous class?

在下面的代码中,我注意到我可以在不引用 HelloWorld 对象的情况下调用 getWorld()?但是隐式 'this' 关键字现在不是指内部匿名 class 吗?如果是这样,为什么我可以调用 getWorld()?

public class HelloWorld {
    public void getWorld() {
        this.setListener(new MyListenerInterface(){
            @Override
            public void innerMethod() {
                getWorld();
            }
        });
    }
}

忽略代码中的递归。

调用 getWorld 你离开了匿名 class 并回到了顶层 class,所以 this 指的是创建匿名对象的对象.

这就像从其他 class 调用一个方法,this 那里引用了一个不同的对象(不是调用者,而是被调用者)。

答案在Section 15.12 of the JLS.

If it is a simple name, that is, just an Identifier, then the name of the method is the Identifier.

If the Identifier appears within the scope of a visible method declaration with that name (§6.3, §6.4.1), then:

  • If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration. The class or interface to search is T.

通过仅使用方法的简单名称,调用哪个方法的解析通过封闭的方法查找,直到找到一个具有该名称的方法,然后尝试使用该方法(或多个方法) ) 找到完全匹配。

这与您使用 this.getWorld() 的情况不同,因为 this 明确指代内部 class 实例。这会导致不同类型的解析(规范的 Typename . Identifier 部分,就在链接引号下方),它不会查看封闭的外部 class.

一个有趣的结果是,您可以通过向内部 class 添加一个具有相同名称但不同元数的方法来使代码停止编译。由于它在尝试确定要解析的 class 实例时仅搜索名称本身,因此它将尝试使用内部 class,但不会找到完全匹配的方法。

所以这个:

public class HelloWorld {
    public void getWorld() {
        this.setListener(new MyListenerInterface(){
            @Override
            public void innerMethod() {
                getWorld();
            }
            void getWorld(int i){}
        });
    }
}

无法编译。方法名称解析将在内部 class 中发现 getWorld,因此将停止向上搜索层次结构。但是当它尝试进行元数解析时,它会看到 class 中的(一个)getWorld 方法中的 none 匹配,并且会失败。

TL;DR - 注意仅使用简单名称与使用 this.method() 完全相同,尽管它通常计算出相同的东西。语言规范有处理这种情况的特定规则,可以允许它在任何封闭实例中查找匹配方法。