我的其他隨筆: 來一局緊張刺激的吃雞——淺談裝飾者模式 一起去開心的購物吧——淺談觀察者模式 記一場精彩的籃球比賽——淺談策略模式 大家好,前幾日連夜更了幾篇Java設計模式的小隨筆,從觀看量來說,我還是很高興的,有很多的朋友通過看了博文,也許接觸了新的知識,也許理解了自己之前沒弄懂的東西,也許只是 ...
聲明:本文為原創,如有轉載請註明轉載與原作者並提供原文鏈接,僅為學習交流,本人才識短淺,如有錯誤,敬請指正
我的其他隨筆:
來一局緊張刺激的吃雞——淺談裝飾者模式
一起去開心的購物吧——淺談觀察者模式
記一場精彩的籃球比賽——淺談策略模式
大家好,前幾日連夜更了幾篇Java設計模式的小隨筆,從觀看量來說,我還是很高興的,有很多的朋友通過看了博文,也許接觸了新的知識,也許理解了自己之前沒弄懂的東西,也許只是加深了自己的相關方面的印象,反正不管怎麼說,如果我淺薄的小隨筆能在大家廣闊的腦海中留下一絲絲漣漪,我都甚感榮幸。
恰逢周末,我也就不打算再更一篇重量級的設計模式相關的文章,人嘛,還是要休息的,接下來準備寫得是比較繁雜的工廠模式和抽象工廠模式,敬請大家期待,如果想看之前的我的陋作的話,可以點擊上面的鏈接。
今天呢,就簡單的講一下Java裡面的泛型數組的一些小知識,屬於本人的一點小總結,如果有錯誤的,請大家多多指正,共同進步。
在Java中,我們不能實例化(註意我說的是實例化)一個參數化類型的數組,但是卻可以參數化數組本身的類型,也許大家覺得有點繞口,沒有關係,我來慢慢解釋,並且通過代碼,讓大家看的更清楚。
第一種情況,不能實例化一個參數化類型的數組,什麼叫參數化類型的數組呢,就是這個數組裡存儲的對象是參數化類型,大家比較熟悉的List<String>就是一個類型參數為String的參數化類型,我們在Java中也稱呼它為泛型。來看代碼(直接粘貼的代碼沒有編譯器的報錯指示,所以我直接截圖):
我們發現報錯了,報錯信息就是Java無法創建參數化類型的數組。
那麼為什麼Java會禁止我們做這樣的事呢,《Thinking in java》一書中指出,由於泛型具有擦除機制,在運行時的類型參數會被擦除,Java只知道存儲的對象是一個Object而已,而對於Java的數組來說,他必須知道它持有的所有對象的具體類型,而泛型的這種運行時擦除機制違反了數組安全檢查的原則。
那麼有其他可以曲線救國的方法嗎,註意我之前所說,雖然我們不能實例化一個參數化類型的數組,但是編譯器也只是檢查實例化而已,而對於創建一個參數化類型數組的引用,卻並不會報錯。
所以我們可以通過創建一個非參數化類型的數組,然後將他強制類型轉換為一個參數化類型數組。即:
然後我們就會發現編譯不再提示報錯,我們來使用一下看看。
正常傳入一個String類型參數的list並不會有任何問題,但當我們傳入一個類型參數為Integer的list時編譯器卻提示我們有錯,報錯原因是類型不合法,數組期望一個List<String>,我們卻傳入了List<Integer>,由此我們知道,通過強轉型實現的參數化類型數組,Java已經獲悉了這個數組在運行時應該持有的具體類型,因此他是一個合法的數組。
這是第一種情況,我們不能實例化參數化類型的數組。
第二種情況,我們可以參數化數組本身的類型。
參數化數組本身的類型,顧名思義,我們不再參數化數組持有的對象的類型,而是將數組應該存儲的對象進行參數化,我們來看一個返回一個數組的參數化方法:
在該參數化方法中,我們傳入了一個數組,返回該數組本身,唯一的引人註目的地方就是數組中的對象類型為泛型。
我們來簡單的測試一下。
其中JR類為我建的一個簡單類,重寫了toString方法便於查看,而不是讓他預設列印對象地址。
下麵是運行結果。
我們發現,無論我們傳入Integer類型數組或String類型數組或自定義對象數組,該參數化方法總能正確的執行,即數組本身的類型被參數化了,但在運行時,被賦予了具體的類型。
事實上,即使我們能參數化數組本身的類型,我們也不能直接創建一個泛型數組,這在編譯時都不被允許。
註意紅色波浪線。
我們可以通過創建Object數組然後將其強轉型為T[ ]來近似實現我們的目的,但這是沒有意義的。
因為在這種情況下,任何Object類型及其子類,也就是除了基本類型之外的所有Java對象都可以放入這個數組中。
通過以上的研究,我們可以發現,想將泛型與數組聯繫起來使用是一件既危險又容易自討沒趣的苦差事,所以在日常使用中,我們最普遍使用泛型的情況就是與Collection與Map聯繫使用,以協助我們快速發現錯誤而不是等到運行時才報出一大串異常。
謝謝大家,今天的泛型數組的相關內容大致就說到這裡了,有問題的話大家可以在下麵評論區交流哦。