java泛型
在JDK1.5增加了泛型機制
泛型程式設計使得編寫的代碼可以被很多不同類型的對象所重用。
類型參數:使得程式具有更好的可讀性和安全性
<b>泛型類的定義</b>
<b></b>
調用:
運作結果:
name1=singsong1
name2=singsong2
T是類型變量,要用<>括起來,并放在類名的後面。當然了泛型類可以有多個類型變量。
如public interface <b>Map<K,V></b>
類型變量使用大寫形式,且比較短。在java庫中,使用變量E表示集合的元素類型,K和V分别表示表的關鍵字與值的類型。T表示“任意類型”
泛型類可看作普通類的工廠。
<b>泛型方法</b>
此方法求最大值
注意,類型變量放在修飾符(這裡是public static)的後面,傳回類的前面。
泛型方法可以定義在普通類中,也可以定義在泛型類中。
在此泛型方法中使用了類型變的限定機制:
<T extends Comparable<T>>
因為要確定T所屬的類有compareTo方法。是以将T限定為現實了Comparable接口的類。
如果傳入的類沒有實作Comparable接口的,調用getMax将會産生一個編譯錯誤。
當然,一個變量類型或通配符可以有多個限定,用“&”分隔(注意:類型變量是用“,”逗号分隔)
如:T <b>extends</b> Comparable<T>& Serializable<T>
在java的繼承中,可以根據需要擁有多個接口超類型,但限定中至多有一個類。如果用一個類作為限定,它必須是限定清單的第一個。
當調用一個泛型方法是,在方法名前的尖括号中放入具體的類型
虛拟機沒有泛型類型對象,即所有對象都屬于普通類。
<b>無論何時定義一個泛型類型,都自動提供了一個相應的原始類型(raw type)。原始類型的名字就是删去類型參數後的泛型類型名。擦除類型變量,并替換為限定類型(無限定的變量用Object)</b>
<b>如:</b>
Person<T>原始類型
原始類型用第一個限定的類型變量來替換,如果沒有就給定限定用Object替換。
如:<b>public</b> <b>class</b> Person<T extends Comparable & Serializable> implements Serializable {
<b>public</b> Person(T name) {
<b>super</b>();
<b>this</b>.name = name;
}
.. .. .. ..
}
原始類型:
<b>public</b> <b>class</b> Person implements Serializable {
<b>public</b> Person(<b>Comparable</b> name) {
<b>編譯器翻譯泛型表達式和泛型方法</b><b></b>
當程式調用泛型方法是,如果擦除傳回類型,編譯器插入強制類型轉換。
如:Person<String> someone=. . .;
編譯器首先調用原始方法Person.getName();
然後将傳回的Object類型強制轉換化為String類型。
當存取一個泛型域時也要插入強制類型轉換。
對一泛型方法要了解當類型擦除時,可能與多态産生沖突。要解決這個問題,就需要編譯器在子類中生成一個相應的橋接方法(bridge method)
<b>總結</b><b></b>
ü 虛拟機中沒有泛型,隻有普通的類和方法。
ü 所有的類型參數都用它們的限定類型替換。
ü 橋接方法被合成來保持多态。
ü 為了保持類型安全。必要時插入強制類型轉換。
<b>使用</b><b>java</b><b>泛型的一些限制與限制,大多數限制都是由類型擦除引起的。</b><b></b>
不能使用基本類型執行個體化類型參數
因為在類型擦除時,沒有限定的類型變量,是用Object類型來限定,而Object不能存儲基本類型。
運作時類型查詢隻适用于原始類型
不能抛出也不能補貨泛型類執行個體
泛型類擴充Throwable都不合法。不能再catch語句中使用類型變量。但是在異常聲明中可以使用類型變量
參數化類型的數值不合法
如果需要收集參數化類型的對象,最好直接使用ArrayList.
不能執行個體化類型變量
泛型類的靜态上下文中類型變量無效
不能再靜态域或方法中引用類型變量
注意擦除後的沖突
泛型規範:要想支援擦除的轉換,就需要強行限制一個類或類型變量不能同時成為兩個接口類型的子類。而這兩個接口是同一接口的不同參數化。
<b>泛型類可以擴充或實作其他的泛型類</b><b></b>