Java基礎之泛型程序設計
泛型程序設計
簡要介紹
類型變量使用大寫形式,且比較短,在Java庫中,使用變量E表示集合的元素類型,K和V分別表示表的關鍵字與值得類型。Object 表示”任意類型”
程序清單使用了Pair類,靜態(tài)的minmax方法遍歷了數(shù)組并同時計算出最大值和最小值。它用一個Pair對象返回了兩個結果。
compareTo 方法只有 Comparable 接口有該方法,所以我們要將T限制為實現(xiàn)了Comparable接口的
的類
類型擦除
無論何時定義一個泛型類型,都自動提供了一個相應的原始類型,原始類型的名字就是刪去參數(shù)后的泛型類型名,擦除類型變量,并替換為限定類型(無限定的變量用Object)
例如:Pair 的原始類型如下所示:
public class Pair <Object>{
private Object name;
private Object bonus;
public Object getFirst() {
return name;
}
public void setFirst(Object name) {
this.name = name;
}
public Object getSecond() {
return bonus;
}
public void setSecond(Object bonus) {
this.bonus = bonus;
}
public Pair(){}
public Pair(Object name, Object bonus) {
this.name = name;
this.bonus = bonus;
}
@Override
public String toString() {
return "Pair{" +
"name=" + name +
", bonus=" + bonus +
'}';
}
類型擦除帶來的方法參數(shù)不統(tǒng)一,編譯器通過橋方法來處理。
與Java泛型轉(zhuǎn)換的事實
虛擬機中沒有泛型,只有普通的類和方法。
所有的類型參數(shù)都用它們的限定類型替換
橋方法被合成來保持多態(tài)
為保持類型安全性,必要時插入強制類型轉(zhuǎn)換。
約束與局限性
不能用基本類型實例化類型參數(shù)
例如沒有 Pair<double>,只有 Pair<Double>
運行時類型查詢只適用于原始類型
例如:
Pair<String> stringPair=new Pair<String>();
Pair<Employee> employeePair=new Pair<Employee>();
if(stringPair.getClass()==employeePair.getClass())
其比較結果是true,這是因為兩次調(diào)用getClass都將返回 Pair.class
不能創(chuàng)建參數(shù)化類型的數(shù)組
例如:
Pair<String>[] table=new Pair<String>[10] //error
Varargs 警告
public static <T> void addAll(Collection<T> coll,T ... ts){
for(t: ts) coll.add(t);
}
現(xiàn)考慮以下調(diào)用:
Collection<Pair<String>> table=...;
Pair<String> pair1=...;
Pair<String> pair2=...;
Pair<String> pair3=...;
addAll(table,pair1,pair2);
為了調(diào)用這個方法,Java虛擬機必須建立一個Pair 數(shù)組。這就違反了前面的規(guī)則。
不過,對于這種情況,規(guī)則有所放松,你只會得到一個警告,而不是錯誤。
可以采取兩種方法來抑制這個警告。一種方法是為包含addAll調(diào)用的方法增加注解@SuppressWarnings(“unchecked”)?;蛘咴贘ava SE 7中,還
可以用@SafeVarargs直接標注addAll方法。
5 不能實例化類型變量
不能使用像new T(…),new T[…] 或T.class 這樣的表達式中的類型變量,例如下面
Pair 構造器就是非法的:
public Pair(){name=new T();bonus=new T();}
類型擦除將T改變成了Object,而且,其本意肯定不希望調(diào)用new Object()。在Java SE 8之后,最好的解決辦法是讓調(diào)用者
提供一個構造器表達式。例如:
Pair<String> p=Pair.makePair(String::new)
6. 不能構造泛型數(shù)組
例如:
public static <T extends Comparable> T[] minmax(T[] a){T[] mm=new T[2];} //error
7. 泛型類的靜態(tài)上下文中類型變量無效
不能再靜態(tài)域或方法中引用類型變量。例如:
“`
public class Signleton {
private static T signleStance; //Error
public static T getSignleStance(){ //True
if(signleStance==null){
return signleStance;
}
}
}
8. 不能拋出或者捕獲泛型類的實例
既不能拋出也不能捕獲泛型類對象。實際上,甚至泛型類擴展Throwable都是不合法的。
例如:以下定義就不能正常編譯:
`public class Problem<T> extends Exception{}`
9. 可以通過 `@SuppressWarnings('unchecked')` 來消除對受查異常的檢查。
### 泛型類型的繼承規(guī)則
1. 通配符的使用
public static void main(String[] args) {
Pair managerPair = new Pair<>();
printBuddies(managerPair);
}
public static void printBuddies(Pair<? extends Employee> employeePair) {
Employee name = employeePair.getFirst();
Employee bonus = employeePair.getSecond();
System.out.println("name:"+name+"bonus:"+bonus);
}
這種情況會編譯報錯
//Test 2
Pair
下面是泛型的綜合應用:
package com.jay.generic;
import com.jay.generic.employee.Employee;
import com.jay.generic.employee.Manager;
/**
* 泛型綜合總結應用
* Created by xiang.wei on 2018/1/21
*
* @author xiang.wei
*/
public class PairTest3 {
public static void main(String[] args) {
Manager ceo = new Manager(“xiang”, 10000);
Manager cfo = new Manager(“l(fā)i”, 8000);
Pair managerPair = new Pair<>(ceo, cfo);
printBuddies(managerPair);
ceo.setBonus(2000);
cfo.setBonus(1000);
Manager[] managers = {ceo, cfo};
minmaxBonus(managers, managerPair);
System.out.println("first:"+managerPair.getFirst().getName()+",second:"+managerPair.getSecond().getName());
maxminBonux(managers,managerPair);
System.out.println("first:"+managerPair.getFirst().getName()+",second:"+managerPair.getSecond().getName());
}
public static void printBuddies(Pair<? extends Employee> pair) {
Employee first = pair.getFirst();
Employee second = pair.getSecond();
System.out.println("first="+first.getName()+"------second="+second.getName());
}
public static void minmaxBonus(Manager[] managers, Pair<? super Manager> result) {
if (managers.length == 0) {
return;
}
Manager min = managers[0];
Manager max = managers[0];
for (int i = 0; i < managers.length; i++) {
if (min.getBonus() > managers[i].getBonus()) {
min = managers[i];
}
if (max.getBonus() < managers[i].getBonus()) {
max = managers[i];
}
}
result.setFirst(min);
result.setSecond(max);
}
public static void maxminBonux(Manager[] managers, Pair<? super Manager> result) {
if (managers.length == 0) {
return;
}
minmaxBonus(managers, result);
PairAlg.swapHelper(result);
}
}
/**
*
*/
class PairAlg {
/**
* @param pair
* @return
*/
public static boolean hasNulls(Pair
作者:碼農(nóng)飛哥
微信公眾號:碼農(nóng)飛哥