答案是Section 15.12 of the JLS。
如果它是一個簡單的名字,也就是一個標識符,那麼方法的名稱就是標識符。
如果出現具有該名稱的可見方法聲明的範圍內的標識符(§6.3,§6.4.1),則:
- 如果有一個封閉類型聲明其中該方法是一成員,讓T成爲最內層的類型聲明。類或接口進行搜索是T.
僅僅通過使用該方法的簡單名稱,來調用哪個方法分辨率查找通過封閉的方法,直到找到一個具有方法與名稱,然後嘗試使用該方法(或多個方法)來查找完全匹配。
這與使用this.getWorld()
的情況不同,因爲this
明確指向內部類實例。這會導致不同類型的分辨率(規範中的Typename . Identifier
部分,僅在鏈接引號的下面),它不會查看封閉的外部類。
這方面的一個有趣的結果是,你可能會導致代碼停止通過添加一個方法到具有相同名稱的內部類編譯,但不同的元數。由於它只是在嘗試確定類實例來解析它時才搜索名稱本身,它將嘗試使用內部類,但找不到完全匹配的方法。
所以這個:
public class HelloWorld {
public void getWorld() {
this.setListener(new MyListenerInterface(){
@Override
public void innerMethod() {
getWorld();
}
void getWorld(int i){}
});
}
}
不會編譯。方法名稱解析將在內部類中發現getWorld
,因此將停止搜索層次結構。但是,當它嘗試執行arity解析時,它將看到類中的(一個)getWorld
方法都不匹配,並且會失敗。
TL; DR - 僅使用簡單的名稱是注意不太一樣使用,即使它通常計算爲同樣的事情。語言規範具有處理這種情況的特定規則,這可以允許它查看任何封閉的實例以找到匹配的方法。
我覺得他問的是Java語言本身的運作。你說得對,這就是它在做什麼,但爲什麼? – jiveturkey