[英]Overload resolution, which method is called
假設我有一個ComponentBase
類,它是ObjectContext
的子類和ObjectContextDecorator
的孫類。
public class ComponentBase extends ObjectContextDecorator {
}
public class ObjectContextDecorator extends ObjectContext {
public void set(String objectTypePath, String characteristicName, Object value) {
//...
}
}
public class ObjectContext {
public void set(String characteristicName, Object value, boolean forced) {
//...
}
}
ObjectContextDecorator
和ObjectContext
的set
方法非常相似。 考慮這個示例代碼:
ComponentBase base = new ComponentBase();
base.set(""OTM4E_EFFLEVEL"", ""IE1 / STD"", true);
兩種方法的簽名都適合被正確調用的方法。 我無法更改方法的簽名,因為它不是我的代碼。
編譯器如何知道我打算調用哪個方法?
我知道在 IDE 上您可以指出您實際打算調用哪個方法,但在這種情況下,我使用類加載器加載一個類,該類具有包含示例代碼的方法。
這一切都在JLS §15.2方法調用表達式中進行了解釋。 它會告訴您如何選擇正確的調用方法。 請注意,這並不總是成功。
在您的特定情況下,這兩種方法是彼此的重載,因此適用第 15.2.2 節“編譯時步驟 2:確定方法簽名”——要調用的重載是在編譯時確定的。 此步驟進一步分為 3 個階段。
第一階段(第 15.12.2.2 節)執行重載決策,不允許裝箱或拆箱轉換,也不允許使用變量元數方法調用。 如果在此階段沒有找到適用的方法,則處理繼續到第二階段。
在第一階段,編譯器嘗試在不允許裝箱轉換的情況下找到適用的方法。 在您的情況下,要調用采用Object
的重載,需要進行裝箱轉換以將boolean
true
轉換為Object
類型,以便在第一階段不會選擇重載。
如果未找到適用於嚴格調用的方法,則適用方法的搜索將繼續第 2 階段 (§15.12.2.3)。
否則,將在嚴格調用適用的方法中選擇最具體的方法(§15.12.2.5)。
好吧,我們正好找到了一種方法,所以我們就選擇那個方法。 沒有歧義。
編譯器如何知道我打算調用哪個方法?
它檢查參數並根據JLS §15.2描述的規則確定哪個更具體
在您的情況下,調用:
base.set("OTM4E_EFFLEVEL", "IE1 / STD", true)
參數是String
, String
, boolean
與第一類匹配(為簡潔起見更改了參數名稱)
public class ObjectContext {
public void set(String s, Object o, boolean b){
//...
}
}
第二個類沒有被調用,因為第三個參數是一個Object
:
public class ObjectContextDecorator extends ObjectContext {
public void set(String s, String ss, Object thisOneRightHere) {
//...
}
}
雖然布爾值true
可以匹配,如果它是自動裝箱的,但第一個更具體。 此處適用的規則是:
第一階段(§15.12.2.2)執行重載決議,不允許裝箱或拆箱轉換
但是,例如,如果您在簽名中使用對象包裝器Boolean
:
public class ObjectContext {
public void set(String s, Object o, Boolean b){ //<-- third param changed from boolean to Boolean
//...
}
}
然后它們將匹配,編譯器將通過以下消息通知您:
> A.java:25: error: reference to set is ambiguous
> base.set("OTM4E_EFFLEVEL", "IE1 / STD", true);
> ^ both method set(String,Object,Boolean) in ObjectContext and method set(String,String,Object) in ObjectContextDecorator match
但在您的示例中並非如此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.