簡體   English   中英

重載解析,調用哪個方法

[英]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) {
       //...
    }
}

ObjectContextDecoratorObjectContextset方法非常相似。 考慮這個示例代碼:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM