1. 程式人生 > >JAVA-初步認識-常用對象API(集合框架-泛型-泛型限定-上限)

JAVA-初步認識-常用對象API(集合框架-泛型-泛型限定-上限)

產生 中標 我們 同時 高級用法 情況下 探討 不一定 port

一.

泛型的基本使用已經說完了,泛型類,泛型接口和泛型方法的體現也已經講述完了。現在講述一下,泛型的高級使用。

來一個String,定義一個集合,裏面存儲的全都是字符串,那我們就明確類型。明確完之後,就導一個包,采用add方法往裏面傳遞幾個字符串。

接著對它進行遍歷,遍歷的時候類型也是字符串,

技術分享圖片

技術分享圖片

運行的時候沒有問題,非常簡單。

但是有一個問題,集合不唯一。其實就是介紹各種不同的情況,來顯示事物的用法,這裏就是顯示泛型的用法。

技術分享圖片

有很多集合同時存在的情況下,如何叠代其中的某一個集合。

再繼續寫叠代器就不合適了,原因是:容器是不斷在變化的,元素是不斷在添加,但是怎麽叠代都是一樣的,為了提高代碼復用性。

技術分享圖片

不論哪個集合都用這個方法來叠代,這個方法是用來打印集合的功能(叠代並打印集合中的元素)。

如果不搞Arraylist集合,搞一個hashset集合也是可以的,但是這個方法只能打印list或者Arraylist。

如果是Arraylist和hashset同時存在,那麽方法中就用collection,提高復用性,擴展性就高多了。

技術分享圖片

collection級別比較高,可以承接list或者hashset。上面的例子中雖然集合不同,但是存儲元素的種類是相同的,下面看存儲不同種類時的情況。

技術分享圖片

這樣一來al2就不能往裏面傳遞了,如果我們寫兩個方法,顯示錯誤,因為,參數類型一致都是集合,都是collection。這兩個方法不能同時存在,因為接收到的全都是集合,這時候該怎麽辦?

技術分享圖片

這時候就是說,方法中集合裏存放的元素種類不確定。當一旦要操作的類型不確定的時候,裏面還不準備用具體類型的情況下,比如說不準備用String,

如果全都是string,那就是下圖的寫法。但是我們不準備用string,或者說不一定用string,可以用另外一種通配符的形式來表示。

技術分享圖片

現在給大家介紹的是泛型的通配符,通通都匹配的符號,這個通配符就是問號?,位置類型。

下圖中不能明確類型,就還是寫it.next()。

技術分享圖片

當我們寫成問號的時候,就什麽都能傳遞。還有一種方式,就是不寫,這也是可以的。原因是:老版本中是沒有泛型的,老版本中定義的方法就沒有泛型,但是我們用的是新版本中的集合,那必須要兼容,但是左側會報警報提示,還是不要這麽寫。運行一下,程序是沒有問題的。

技術分享圖片

上面就是通配符的使用,再說一點就是,這個問號和後面寫的一種方式差不多。未知類型就是當指的是當不明確類型情況下,可以用問號來表示。

有人說,我們能不能這樣做,區別不大,將問號換成字母,運行一樣是可以的。

技術分享圖片

有點區別,如果用T來書寫的話,是可以寫成下面的形式的,當程序在運行的時候,這裏面只要有一個類型具備了,都是統一類型。只不過這方法是靜態的,不需要對象去明確,直接調用就可以了,這和問號的區別並不大。有必要寫這麽麻煩麽?沒有。

技術分享圖片

區別是什麽呢?如果有指定T的話,就意味著這個T能代表一個具體類型,並能被操作。具體的顯示如下,當我們有些工具類中帶有返回值為t的話,這個類型可以進行操作,而對於問號來講,只僅在不明確類型並不對這個類型進行操作,用問號來表示。像這樣僅僅是打印,就可以使用問號的表現形式,沒必要寫成字母的這種復雜的代碼,最終調用object的toString方法,這就是問號通配符的特點。

技術分享圖片

技術分享圖片

上面的都是通配符的簡單使用,下面描述一下它的高級用法。(後面這些知識點的介紹都是建立在前面知識的基礎上展開的,一個發展的過程)

例子中,往集合裏傳遞的是對象worker,為了後期打印的效果,將worker類中的tostring方法覆寫。同時,學生類裏面也進行相同的修改,因為是繼承過來的,所以可以采用getname這樣的方法。這是父類有的,不是本類私有的,

技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

其它問號的部分不變,最終的結果顯示worker和integer都打印出來了,任意類型都可以

現在我們有一個需求,有兩個集合,除了worker就是student,

技術分享圖片

現在探討worker類和String一起存在時的情況。

現在想打印一個容器中的元素,但是這個容器得有一個條件,不是什麽都打印,只打印person的子類。既不是打印一個類(如果是一個類,那麽T就可以明確),如果是打印所有類,則是問號表示。現在是想打印一部分類,就是打印worker,和student。有人說直接用person就可以了,但是左側的小圖標顯示這是錯誤的。

技術分享圖片

person是一個單獨的類型,而worker和student也是單獨的類型,它們之間存在繼承關系,但是在這裏collection裏面只能存儲person的對象,這是一個具體類型。

舉個例子來看,寫全了如下所示,左右兩邊的泛型不匹配。現在有一集合al,如果它們可以用繼承關系來表現的話,集合聲明的時候說裏面存的全都是人,也就是說無論是worker還是student都可以存進來。但是右側的實體中標明只能存student,這就產生了矛盾(多態和泛型在這點上的區別是在哪?)。一般情況下寫泛型要具備左右兩邊一致的特點。

技術分享圖片

但是我們現在就想要接收worker和student,要想接收person或者person的子類對象,可以這麽弄。person子類對象很多,不確定,寫法如下。這裏還有波浪線,導個包就可以了。

技術分享圖片

可上面所講的知識點就是泛型的限定,這屬於泛型的高級應用。以前在用object的時候,只要寫個object,那麽什麽都可以解決,現在做了限定以後,只能有一部分類型能進來,如果不是這個類型或它的子類,那麽就直接編譯失敗。以前是編譯沒事,運行出事。

現在java的很多更新都是將運行時期的錯誤,往編譯時期轉,這樣更加的安全。

泛型的限定知識點具體的寫法如下,限定之後,可以直接拿繼承方法。只要存進來都是它的子類的話,編譯時檢測都是對的。取得時候,都可以用父類來取,不能用student取是必然得,因為是問號,泛型限定中第一種體現搞定。在遍歷的時候,貌似存在能否直接調用父類方法的問題。

技術分享圖片

JAVA-初步認識-常用對象API(集合框架-泛型-泛型限定-上限)