JAVA 重載方法,參數為NULL時,調用的處理 (精確性原則)

來源:互聯網
上載者:User

標籤:system   string   item 1   解釋   有一個   csdn   main   class   style   

引子:大家可以思考一下下面程式的輸出結果

public class TestNull {      public void show(String a){          System.out.println("String");      }      public void show(Object o){          System.out.println("Object");      }      public static void main(String args[]){          TestMain t = new TestMain();          t.show(null);      }  }  

啟動並執行結果是:

String

解釋(主要是重載函數調用時精確性的問題):
《java解惑》這本書謎題46解釋了這種情況。下面內容摘自《Java解惑》

謎題46:令人混淆的構造器案例
本謎題呈現給你了兩個容易令人混淆的構造器。main方法調用了一個構造器,但是它調用的到底是哪一個呢?該程式的輸出取決於這個問題的答案。那麼它到底會列印出什麼呢?甚至它是否是合法的呢?

public class Confusing {      private Confusing(Object o) {          System.out.println("Object");      }      private Confusing(double[] dArray) {         System.out.println("double array");      }      public static void main(String[] args) {          new Confusing(null);      }}

傳遞給構造器的參數是一個空的對象的引用,因此,初看起來,改程式好像應該調用參數類型為Object的重載版本,並且將列印出Object。另一方面,數組也是參考型別,因此Null也可以應用於類型是double[]的重載版本。由此可能會得出結論:

  這個調用是模稜兩可的,改程式應該是不能編譯的

如果你試著去運行程式,就會發現我之前的直觀猜測是不對的:該程式列印 的是

double array

這種行為有悖常理,但是有一個很好的理由可以解釋它,

一:選取所有可獲得的並可以應用的構造器或方法

二:在第一步選取的方法或者構造器中選擇最精確的一個 ,二第二個方法就是缺乏精確性

  在我們的程式中,兩個構造器都是可獲得 並且可應用的。構造器Confusing(Object)可以接受任何傳遞給Confusing(double[ ])的參數,因此Confusing(Object)相對缺乏精確性。(每一個double數組都是一個Object,但是每一個Object並不一定是 一個double數組。)因此,最精確的構造器就是Confusing(double[ ]),這也就解釋了為什麼程式會產生這樣的輸出。

理解本謎題的關鍵在於在測試哪一個方法或構造器最精確時,這些測試沒有使用實際的參數:即出現在調用中的參數。這些參數只是被用來確定哪一個重載版本是可應用的。一旦編譯器確定了哪些重載版本是可獲得且可應用的,它就會選擇最精確的一個重載版本,而此時使用的僅僅是形式參數:即出現在聲明中的參數。

要想用一個null參數來調用Confusing(Object)構造器,你需要這樣寫代碼:

以這種方式來在多個重載版本中進行選擇是相當令人不快的。在你的API 中,應該確保不會讓用戶端走這種極端。理想狀態下,你應該避免使用重載:為不同的方法取不同的名稱。當然,有時候這無法實現,例如,構造器就沒有名稱,因 而也就無法被賦予不同的名稱。然而,你可以通過將構造器設定為私人的並提供公有的靜態工廠,以此來緩解這個問題[EJ Item 1]。如果構造器有許多參數,你可以用Builder模式[Gamma95]來減少對重載版本的需求量。
如果你確實進行了重載,那麼請確保所有的重載版本所接受的參數類型都互不相容,這樣,任何兩個重載版本都不會同時是可應用的。如果做不到這一點,那麼就請確保所有可應用的重載版本都具有相同的行為[EJ Item 26]。
總之,重載版本的解析可能會產生混淆。應該儘可能地避免重載,如果你必須進行重載,那麼你必須遵守上述方針,以最小化這種混淆。如果一個設計糟糕的API強制你在不同的重載版本之間進行選擇,那麼請將實際的參數轉型為你希望調用的重載版本的形式參數所具有的類型。

 

參考文檔:8088305

 

JAVA 重載方法,參數為NULL時,調用的處理 (精確性原則)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.