北京北大青鳥學(xué)校學(xué)術(shù)部講師將繼續(xù)講解關(guān)于Java泛型的技術(shù)知識(shí),關(guān)于Java泛型的定義、相關(guān)例子等請(qǐng)參考之前的幾篇文章,在這里就不做陳述了。今天這篇文章,將主講介紹一下Java類庫中的泛型(北大青鳥課程)
集合類
北京北大青鳥學(xué)校專家介紹:到目前為止,Java 類庫中泛型支持存在最多的地方就是集合框架。就像容器類是 C++ 語言中模板的主要?jiǎng)訖C(jī)一樣(參閱 附錄 A:與 C++ 模板的比較)(盡管它們隨后用于很多別的用途),改善集合類的類型安全是 Java 語言中泛型的主要?jiǎng)訖C(jī)。集合類也充當(dāng)如何使用泛型的模型,因?yàn)樗鼈冄菔玖朔盒偷膸缀跛械臉?biāo)準(zhǔn)技巧和方言。(北大青鳥課程)
所有的標(biāo)準(zhǔn)集合接口都是泛型化的 —— Collection
集合類也使用泛型的許多“技巧”和方言,比如上限通配符和下限通配符。例如,在接口 Collection
interface Collection
boolean addAll(Collection extends V>);
}
該定義組合了通配符類型參數(shù)和有限制類型參數(shù),允許您將 Collection
北京北大青鳥學(xué)校專家提醒:如果類庫將 addAll() 定義為接受 Collection
應(yīng)該可以將 addAll() 的類型參數(shù)定義為 Collection
作為泛型化一個(gè)類(如果不小心的話)如何會(huì)更改其語義的一個(gè)更加微妙的例子,注意 Collection.removeAll() 的參數(shù)的類型是 Collection>,而不是 Collection extends V>。這是因?yàn)閭鬟f混合類型的集合給 removeAll() 是可接受的,并且更加限制地定義 removeAll 將會(huì)更改方法的語義和有用性。(北大青鳥課程)
其他容器類
北京北大青鳥學(xué)校專家介紹:除了集合類之外,Java 類庫中還有幾個(gè)其他的類也充當(dāng)值的容器。這些類包括 WeakReference、SoftReference 和 ThreadLocal。它們都已經(jīng)在其包含的值的類型上泛型化了,所以 WeakReference
泛型不止用于容器
泛型最常見最直觀的使用是容器類,比如集合類或引用類(比如 WeakReference
像 Comparable
Comparable
Comparable 接口已經(jīng)泛型化了,所以實(shí)現(xiàn) Comparable 的對(duì)象聲明它可以與什么類型進(jìn)行比較。北京北大青鳥學(xué)校專家總結(jié):(通常,這是對(duì)象本身的類型,但是有時(shí)也可能是父類。)
public interface Comparable
public boolean compareTo(T other);
}
所以 Comparable 接口包含一個(gè)類型參數(shù) T,該參數(shù)是一個(gè)實(shí)現(xiàn) Comparable 的類可以與之比較的對(duì)象的類型。這意味著如果定義一個(gè)實(shí)現(xiàn) Comparable 的類,比如 String,就必須不僅聲明類支持比較,還要聲明它可與什么比較(通常是與它本身比較):
public class String implements Comparable
現(xiàn)在來考慮一個(gè)二元 max() 方法的實(shí)現(xiàn)。您想要接受兩個(gè)相同類型的參數(shù),二者都是 Comparable,并且相互之間是 Comparable。幸運(yùn)的是,如果使用泛型方法和有限制類型參數(shù)的話,這相當(dāng)直觀:
public static
if (t1.compareTo(t2) > 0)
return t1;
else
return t2;
}
北京北大青鳥學(xué)校專家介紹:在本例中,您定義了一個(gè)泛型方法,在類型 T 上泛型化,您約束該類型擴(kuò)展(實(shí)現(xiàn)) Comparable
更好的是,編譯器將使用類型推理來確定當(dāng)調(diào)用 max() 時(shí) T 的值表示什么意思。所以根本不用指定 T,下面的調(diào)用就能工作:
String s = max("moo", "bark");
編譯器將計(jì)算出 T 的預(yù)定值是 String,因此它將進(jìn)行編譯和類型檢查。但是如果您試圖用不實(shí)現(xiàn) Comparable
Class
類 Class 已經(jīng)泛型化了,但是很多人一開始都感覺其泛型化的方式很混亂。Class
在以前的 JDK 中,Class.newInstance() 方法的定義返回 Object,您很可能要將該返回類型強(qiáng)制轉(zhuǎn)換為另一種類型:
class Class {
Object newInstance();
}
但是使用泛型,您定義 Class.newInstance() 方法具有一個(gè)更加特定的返回類型:
class Class
T newInstance();
}(北大青鳥課程)
如何創(chuàng)建一個(gè) Class
讓 Foo.class 是 Class
考慮一個(gè)方法,它從數(shù)據(jù)庫檢索一組對(duì)象,并返回 JavaBeans 對(duì)象的一個(gè)集合。您通過反射來實(shí)例化和初始化創(chuàng)建的對(duì)象,但是這并不意味著類型安全必須完全被拋至腦后。考慮下面這個(gè)方法:
public static
// Use Selector to select rows
List
for (/* iterate over results */) {
T row = c.newInstance();
// use reflection to set fields from result
list.add(row);
}
return list;
}
(北大青鳥課程)
可以像下面這樣簡單地調(diào)用該方法:
List
編譯器將會(huì)根據(jù) FooRecord.class 是 Class
用 Class
Collection 接口包含一個(gè)方法,用于將集合的內(nèi)容復(fù)制到一個(gè)調(diào)用者指定類型的數(shù)組中:
public Object[] toArray(Object[] prototypeArray) { ... }
toArray(Object[]) 的語義是,如果傳遞的數(shù)組足夠大,就會(huì)使用它來保存結(jié)果,否則,就會(huì)使用反射分配一個(gè)相同類型的新數(shù)組。一般來說,單獨(dú)傳遞一個(gè)數(shù)組作為參數(shù)來提供想要的返回類型是一個(gè)小技巧,但是在引入泛型之前,這是與方法交流類型信息最方便的方式。
有了泛型,就可以用一種更加直觀的方式來做這件事。不像上面這樣定義 toArray(),泛型 toArray() 可能看起來像下面這樣:
public
調(diào)用這樣一個(gè) toArray() 方法很簡單:
FooBar[] fba = something.toArray(FooBar.class);
Collection 接口還沒有改變?yōu)槭褂迷摷夹g(shù),因?yàn)檫@會(huì)破壞許多現(xiàn)有的集合實(shí)現(xiàn)。但是如果使用泛型從新構(gòu)建 Collection,則當(dāng)然會(huì)使用該方言來指定它想要返回值是哪種類型。
Enum
JDK 5.0 中 Java 語言另一個(gè)增加的特性是枚舉。當(dāng)您使用 enum 關(guān)鍵字聲明一個(gè)枚舉時(shí),編譯器就會(huì)在內(nèi)部為您生成一個(gè)類,用于擴(kuò)展 Enum 并為枚舉的每個(gè)值聲明靜態(tài)實(shí)例。所以如果您說:
public enum Suit {HEART, DIAMOND, CLUB, SPADE};
編譯器就會(huì)在內(nèi)部生成一個(gè)叫做 Suit 的類,該類擴(kuò)展 java.lang.Enum
與 Class 一樣,Enum 也是一個(gè)泛型類。但是與 Class 不同,它的簽名稍微更復(fù)雜一些:
class Enum
這究竟是什么意思?這難道不會(huì)導(dǎo)致無限遞歸?
我們逐步來分析。類型參數(shù) E 用于 Enum 的各種方法中,比如 compareTo() 或 getDeclaringClass()。為了這些方法的類型安全,Enum 類必須在枚舉的類上泛型化。
所以 extends Enum
北京北大青鳥學(xué)校專家介紹,該部分又具有兩個(gè)部分。第一部分指出,作為 Enum 的類型參數(shù)的類本身必須是 Enum 的子類型,所以您不能聲明一個(gè)類 X 擴(kuò)展 Enum
總之,Enum 是一個(gè)參數(shù)化的類型,只可以為它的子類型實(shí)例化,并且這些子類型然后將根據(jù)子類型來繼承方法。幸運(yùn)的是,在 Enum 情況下,編譯器為您做這些工作,一切都很好。(北京北大青鳥學(xué)校,未完待續(xù))