導語
這裡是導語。對,沒錯,這裡就是導語,沒有前幾次的代碼情書。喜歡情書的關注我,去看我之前的Java文章吧。
主要內容
泛型技術的產生背景
泛型操作的實現
通配符的使用
泛型接口
泛型方法
具體內容
泛型的引出
現在要求定義一個表示座標的操作類(Point),在這個類裡面要求保存有以下幾種座標:
保存數字:x = 10、y = 20。
保存小數:x = 10.2、y = 20.3。
保存字符串:x = 東經20度、y = 北緯15度。
現在這個Point類設計的關鍵就在於x與y這兩個變量的類型設計上。必須有一種類型可以保存這三類數據。首先想到的一定是Object類型:
int:int自動裝箱為Integer,Integer向上轉型為Object。
double:double自動裝箱為Double,Double向上轉型為Object。
String:直接向上轉型為Object。
範例:初期設計如下
下面重複的演示三個程序,分別使用各個不同的數據類型。
在Point類裡面保存整型數據
輸出結果
在Point類裡面保存小數
輸出結果
在Point類裡面保存字符串
輸出結果
此時的代碼已經利用了Object數據類型解決了一切的開發問題,可是解決的關係是靠的是Object,於是失敗的關鍵也在於Object。
範例:觀察錯誤的代碼
代碼不需要執行就可以看到程序的問題,因為在存放的時候是int(Integer),而取的時候使用的是String,兩個沒有發生關係的對象之間要發生強制轉換,就一定會產生ClassCastException。
向上轉型的核心目的在於統一操作的參數上,而向下轉型的目的是操作子類的特殊功能,可是現在的問題發現向下轉換是一件非常不安全的操作,那麼這一操作應該在代碼運行之前就已經能夠自動的排查出來這是最好的選擇。可是之前的技術做不到。
泛型操作的實現
從JDK1.5之後開始增加了泛型技術,而泛型技術的核心意義在於:類的定義的時候,可以使用一個標記,此標記就表示類中屬性或方法參數的類型標記,在使用的時候才動態的設置類型。
範例:修改代碼
在使用Point類的時候才去設置標記的內容,也就是設置了類中的屬性的類型。
使用String
使用了泛型之後,所有類中屬性的類型都是動態設置的,而所有使用泛型標記的方法參數類型也都發生改變,這樣就相當於避免了向下轉型的問題,從而解決了類轉換的安全隱患。
但是需要特別說明的是,如果想要使用泛型,那麼它能夠採用的類型只能夠是類,即:不能是基本類型,只能夠是引用類型(可以使用Integer)。
對於泛型有兩點說明:
如果在使用泛型類或者是接口的時候,沒有設置泛型的具體類型,那麼會出現編譯時的警告,同是為了保證程序不出錯,所有的泛型都將使用Object表示。
從JDK1.7開始可以簡化聲明泛型。
在JDK1.7之後實例化的時候可以寫成:
通配符
為了更好的理解通配符的作用,下面先來觀察一段程序。
輸出結果
以上代碼為Message類設置的是一個String型的泛型類型,但是如果換成其它類型就不能夠使用了。
先看一組錯誤代碼
正確的代碼如下
在“?”通配符基礎上還會有兩個子的通配符:
? extends類:設置泛型上限,可以在聲明上和方法參數上使用。
? extends Number:意味著可以設置Number或者Number的子類(Integer、Double...)。
? super類:設置泛型下限,方法參數上使用。
? super String:意味著只能夠設置String或者是它的父類Object。
範例:設置泛型的上限
如果設置了非Number或者其子類的話,那麼將出現語法錯誤。
範例:設置泛型下限
泛型接口
在之前都是將泛型定義在了一個類裡面,那麼泛型也可以定義在接口上聲明,稱為泛型接口。
範例:定義泛型接口
定義子類有兩種形式。
形式一:在子類繼續設置泛型
形式二:在子類不設置泛型,而為父接口明確的定義一個泛型類型
泛型方法
泛型方法不一定要定義在支持泛型的類裡面。
範例:泛型方法定義
總結
泛型解決的是向下轉型所帶來的安全隱患,其核心的組成就是在聲明類或接口的時候不設置參數或屬性的類型。
“?”可以接收任意的泛型類型,只能夠取出,但是不能夠修改。
學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入Java學習交流群346942462,我們一起學Java!