在下面的代码中,我注意到我可以在不引用HelloWorld对象的情况下调用getWorld()?但并不是隐含的'这个'关键字现在指的是内部匿名类?如果是这样,为什么我能够调用getWorld()?
public class HelloWorld {
public void getWorld() {
this.setListener(new MyListenerInterface(){
@Override
public void innerMethod() {
getWorld();
}
});
}
}
忽略代码中的递归。
答案 0 :(得分:2)
如果它是一个简单的名称,即只是一个标识符,那么该方法的名称就是标识符。
如果标识符出现在具有该名称的可见方法声明的范围内(§6.3,§6.4.1),则:
- 如果存在该方法为成员的封闭类型声明,则让T为最内层的类型声明。要搜索的类或接口是T.
通过仅使用方法的简单名称,调用哪个方法的分辨率通过封闭方法查找,直到找到具有该名称的方法,然后尝试使用该方法(或方法)找到完全匹配。
这与使用this.getWorld()
的情况不同,因为this
明确地引用内部类实例。这导致了不同类型的分辨率(规范的Typename . Identifier
部分,正好在链接的引用之下),它不会查看封闭的外部类。
这样做的一个有趣结果是,您可以通过向具有相同名称但具有不同arity的内部类添加方法来使代码停止编译。因为它只是在尝试确定要解析它的类实例时才搜索名称本身,所以它将尝试使用内部类,但找不到完全匹配的方法。
所以这个:
public class HelloWorld {
public void getWorld() {
this.setListener(new MyListenerInterface(){
@Override
public void innerMethod() {
getWorld();
}
void getWorld(int i){}
});
}
}
不会编译。方法名称解析将在内部类中发现getWorld
,因此将停止搜索层次结构。但是当它试图进行arity解析时,它会看到类中的(一个)getWorld
方法都没有匹配,并且会失败。
TL; DR - 仅使用简单名称与使用this.method()
完全相同,即使它通常评估为相同的东西。语言规范具有处理该情况的特定规则,这可以允许它在任何封闭的实例中查找以找到匹配的方法。
答案 1 :(得分:1)
调用getWorld
你离开匿名类并返回顶级类,因此this
指的是创建匿名类的对象。
就像从其他类调用一个方法,this
引用一个不同的对象(不是调用者,而是调用者)。