天天看點

為什麼Java中的HashMap<K, V>的get函數是get(Object key),而不是get(K key)?

幫别人的代碼改bug,發現有一大堆bug是由get或者remove傳遞進去的參數類型不比對而造成的。

比如:

上面的代碼輸出是null。

一般人很難發現傳遞進去的int和short類型不比對,而且ide,編譯器也沒有提示。當然通過一些分析工具可以檢查出來。

真的感到很困惑,java中的容器的一些函數,參數都是object類型,如hashmap中的get,remove函數,set中的contains函數。

為什麼不明确它們的類型?這樣編譯器可以檢查出類型不比對的錯誤。

google之,google的一個工程師給出了答案:http://smallwig.blogspot.com/2007/12/why-does-setcontains-take-object-not-e.html

為了簡單起見,以set容器為例:

定義一個簡單的s,隻有一個簡單的contains函數:

假如我們有個函數,想要處理foo類的集合:

要是我們想能同時處理foo類的子類(如subfoo)的集合,那應該這樣定義:

一切看起來很好,但是如果我們把代碼都合起來,就會發現悲劇了:

這時編譯器不幹了,它表示不能工作了。

原來在s<k>類的定義中,我們明确contains(k  k)函數隻能接受一個明确類型的參數。

但是在dosomereading函數中,編譯器無法确定到底是什麼類型,它是foo類型,還是subfoo類型,還是subsubfoo類型?

編譯器無從得知,是以它隻允許null類型的參數。

===========================================================

對于這個解析,話說還是有點郁悶。

也有另外的解析,認為和equals函數有關系。不過感覺不大靠譜,這個隻能說是一些另類的應用。

http://stackoverflow.com/questions/857420/what-are-the-reasons-why-map-getobject-key-is-not-fully-generic