讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議98:建議採用的順序是List<T>、List<?>、List<Object> >

建議98:建議採用的順序是List<T>、List<?>、List<Object>

List<T>、List<?>、List<Object>這三者都可以容納所有的對象,但使用的順序應該是首選List<T>,次之List<?>,最後選擇List<Object>,原因如下:

(1)List<T>是確定的某一個類型

List<T>表示的是List集合中的元素都為T類型,具體類型在運行期決定;List<?>表示的是任意類型,與List<T>類似,而List<Object>則表示List集合中的所有元素為Object類型,因為Object是所有類的父類,所以List<Object>也可以容納所有的類類型,從這一字面意義上分析,List<T>更符合習慣:編碼者知道它是某一個類型,只是在運行期才確定而已。

(2)List<T>可以進行讀寫操作

List<T>可以進行諸如add、remove等操作,因為它的類型是固定的T類型,在編碼期不需要進行任何的轉型操作。

List<?>是只讀類型的,不能進行增加、修改操作,因為編譯器不知道List中容納的是什麼類型的元素,也就無法校驗類型是否安全了,而且List<?>讀取出的元素都是Object類型的,需要主動轉型,所以它經常用於泛型方法的返回值。注意,List<?>雖然無法增加、修改元素,但是卻可以刪除元素,比如執行remove、clear等方法,那是因為它的刪除動作與泛型類型無關。

List<Object>也可以讀寫操作,但是它執行寫入操作時需要向上轉型(Up cast),在讀取數據後需要向下轉型(Downcast),而此時已經失去了泛型存在的意義了。

打個比方,有一個籃子用來容納物品,List<T>的意思是說,「嘿,我這裡有一個籃子,可以容納固定類別的東西,比如西瓜、番茄等」。List<?>的意思是說「嘿,我也有一個籃子,我可以容納任何東西,只要是你想得到的」。而List<Object>就更有意思了,它說「嘿,我也有一個籃子,我可以容納所有物質,只要你認為是物質的東西就都可以容納進來」。

推而廣之,Dao<T>應該比Dao<?>、Dao<Object>更先採用,Desc<Person>則比Desc<?>、Desc<Object>更優先採用。