問題的引入
classify方法被重載了厂榛,而要調(diào)用那個重載方法是在編譯時做出決定的。
雖然for循環(huán)中的三次迭代的運行時類型是不同的樟澜,但這并不影響對重載方法的選擇瞳收。
因為該參數(shù)的編譯時類型為Collection<?>,所以,唯一合適的重載方法是第三個:classify(Collection c)猴伶。
重載與重寫的區(qū)別
對于重載方法的選擇是靜態(tài)的课舍,而對于被覆蓋的方法的選擇則是動態(tài)的塌西。
選擇被覆蓋的方法的正確版本是在運行時進行的,選擇的依據(jù)是被調(diào)用方法所在對象的運行時類型筝尾。
如何修復引入的問題
最佳修正方案是:用單個方法來替換這三個重載的classify方法捡需,并在這個方法中做一個顯式的instanceof測試:
覆蓋機制是規(guī)范,而重載機制是例外筹淫,所以覆蓋機制滿足了人們對于方法調(diào)用行為的期望站辉。
如果編寫出來的代碼的行為可能使程序員感到困惑,它就是很槽糕的實踐损姜。
應該避免胡亂地使用重載機制饰剥。
建議
安全而保守的策略是,永遠不要導出兩個具有相同參數(shù)數(shù)目的重載方法薛匪。
如果方法使用可變參數(shù)捐川,保守的策略是根本不要重載它。
始終給方法起不同的名稱逸尖,而不使用重載機制古沥。
對于每一對重載方法,至少有一個對應的參數(shù)在兩個重載方法中具有“根本不同”的類型娇跟。
如果重載方法在同樣的參數(shù)上被調(diào)用時岩齿,執(zhí)行相同的功能,重載就不會帶來危害苞俘。
確保這種行為的標準做法是盹沈,讓更具體化的重載方法把調(diào)用轉(zhuǎn)發(fā)給更一般化的重載方法。
例如String類的:
自動裝箱
在JDK5之前吃谣,所有的基本類型都根本不同于所有的引用類型乞封,但是自動裝箱改變了這種情況。
如何解決這個問題:
總結(jié)
避免:同一組參數(shù)只需經(jīng)過類型轉(zhuǎn)換就可以被傳遞給不同的重載方法岗憋。
當傳遞相同的參數(shù)時肃晚,所有重載方法的行為必須一致。