簡體   English   中英

在具有重載構造函數的類中傳遞null時首先調用哪個構造函數?

[英]Which constructor is called first while passing null in the class having overloaded constructor?

下面是具有3個重載構造函數的java類:

public class Test {

    public Test(Object i){
        System.out.println("Object invoked");
    }

    public Test(String i){
        System.out.println("String invoked");
    }

    public Test(int k){
        System.out.println("Integer invoked");
    }

    public static void main(String[] args) throws Exception {

        Test t = new Test(null);
    }
}

如果在創建新的類實例時傳遞了null值,那么將調用哪個構造函數? 是什么原因 ?

Java總是選擇適用於您傳遞的參數的最具體的方法(或構造函數)。 在這種情況下,這是String構造函數 - StringObject的子類。

想想如果你有什么會發生什么

new Test("some string")

無論ObjectString構造函數會在這里是適用的。 畢竟,參數既是Object又是String 但是 ,很明顯,將調用String構造函數,因為它比Object構造函數更具體,並且在給定參數的情況下仍然適用。

null也不例外; 這兩個構造函數仍然適用,並且出於同樣的原因,仍然在Object構造函數上選擇了String構造函數。

現在,如果存在兩個同樣“特定”的構造函數(例如,如果您有一個Integer構造函數),則在調用Test(null)時會出現編譯錯誤。

這在JLS§15.12.2中有更詳細的描述:

第二步搜索上一步中為成員方法確定的類型。 此步驟使用方法的名稱和參數表達式的類型來定位可訪問和適用的方法,即可以在給定參數上正確調用的聲明。

可能存在多於一種這樣的方法,在這種情況下,選擇最具體的方法。 最具體方法的描述符(簽名加返回類型)是在運行時用於執行方法分派的方法。

JLS§15.12.2.5中概述了確定哪種方法最具體的明確過程。

答案是:調用Test(String)

為什么?

在確定將調用哪一組重載方法時,Java編譯器將嘗試匹配最具體的類型。 使用自動裝箱之前 ,它將首先嘗試匹配簽名。 (@arshajii提供了關於Java語言規范的完美參考)

這里, Object是類型系統中最抽象的類。 來自Object String子類因此更具體/具體。

這背后的邏輯是,如果您使用更具體類型的參數重載方法,您可能希望對該對象執行更多操作(當您進行子類化時,通常會添加方法)。 如果方法簽名確定以另一種方式工作(即更抽象類型的簽名獲勝;這里, Test(Object) ),那么將不會調用任何更具體的簽名。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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