-
限制泛型
第三篇文章中的例子在上面的例子中,由于沒(méi)有限制class WithGenerics<T>類型持有者T的范圍筏养,實(shí)際上這里的限定類型相當(dāng)于Object丧慈,這和“Object泛型”實(shí)質(zhì)是一樣的孟辑。限制比如我們要限制T為集合接口類型山叮。只需要這么做:
class WithGenerics<T extends Collection>,這樣類中的泛型T只能是Collection接口的實(shí)現(xiàn)類博脑,傳入非Collection接口編譯會(huì)出錯(cuò)憎乙。
注意:<T extends Collection>這里的限定使用關(guān)鍵字extends,后面可以是類也可以是接口叉趣。但這里的extends已經(jīng)不是繼承的含義了泞边,應(yīng)該理解為T(mén)類型是實(shí)現(xiàn)Collection接口的類型,或者T是繼承了XX類的類型疗杉。
public class WithExtendGenerics<T extends Collection> {
public WithExtendGenerics(T var) {
this.var = var;
}
public Integer getSize() {
return var.size();
}
public T getVar() {
return var;
}
public void setVar(T var) {
this.var = var;
}
public void showTypeName() {
System.out.println(String.format("參數(shù)的實(shí)際類型:%s", var.getClass().getSimpleName()));
}
private T var;
public void test(WithExtendGenerics<? extends Collection> var) {
if (null == var) {
return;
}
var.getSize();
}
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("123");
WithExtendGenerics<ArrayList<String>> w1 = new WithExtendGenerics<>(arrayList);
w1.showTypeName();
ArrayList<String> var1 = w1.getVar();
System.out.println(String.format("參數(shù)值是:%s size:{}", var1,w1.getSize()));
WithExtendGenerics<? extends Collection> var = new WithExtendGenerics<>(null);
}
}
-
多接口限制
雖然Java泛型簡(jiǎn)單的用 extends 統(tǒng)一的表示了原有的 extends 和 implements 的概念阵谚,但仍要遵循應(yīng)用的體系,Java 只能繼承一個(gè)類烟具,但可以實(shí)現(xiàn)多個(gè)接口梢什,所以你的某個(gè)類型需要用 extends 限定,且有多種類型的時(shí)候朝聋,只能存在一個(gè)是類嗡午,并且類寫(xiě)在第一位,接口列在后面冀痕,也就是:
<T extends SomeClass & interface1 & interface2 & interface3>
這里的例子僅演示了泛型方法的類型限定荔睹,對(duì)于泛型類中類型參數(shù)的限制用完全一樣的規(guī)則,只是加在類聲明的頭部言蛇,如:
public class Demo<T extends Comparable & Serializable> {
// T類型就可以用Comparable聲明的方法和Seriablizable所擁有的特性了
}
-
通配符泛型
為了解決類型被限制死了不能動(dòng)態(tài)根據(jù)實(shí)例來(lái)確定的缺點(diǎn)僻他,引入了“通配符泛型”,針對(duì)上面的例子腊尚,使用通配泛型格式為<? extends Collection>吨拗,“?”代表未知類型婿斥,這個(gè)類型是實(shí)現(xiàn)Collection接口劝篷。那么上面實(shí)現(xiàn)的方式可以寫(xiě)為:
WithExtendGenerics<? extends Collection> var = null;
var = new WithExtendGenerics<>(new ArrayList<String>());
- 如果只指定了<?>,而沒(méi)有extends受扳,則默認(rèn)是允許Object及其下的任何Java類了携龟。也就是任意類兔跌。
- 通配符泛型不單可以向上限制勘高,如<? extends Collection>,還可以向下限制,如<? super Double>华望,表示類型只能接受Double及其上層父類類型蕊蝗,如Number、Object類型的實(shí)例赖舟。
- 泛型類定義可以有多個(gè)泛型參數(shù)蓬戚,中間用逗號(hào)隔開(kāi),還可以定義泛型接口宾抓,泛型方法子漩。這些都與泛型類中泛型的使用規(guī)則類似。
-
泛型方法
是否擁有泛型方法石洗,與其所在的類是否泛型沒(méi)有關(guān)系幢泼。要定義泛型方法,只需將泛型參數(shù)列表置于返回值前讲衫。
public <T> void testFun(T var) {
System.out.println(String.format("參數(shù)的實(shí)際類型:%s", var.getClass().getSimpleName()));
}
使用泛型方法時(shí)缕棵,不必指明參數(shù)類型,編譯器會(huì)自己找出具體的類型涉兽。泛型方法除了定義不同招驴,調(diào)用就像普通方法一樣。