国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java核心技術筆記-第12章

2019-11-06 07:43:03
字體:
來源:轉載
供稿:網友

泛型

1.

class Test<T> //也可以有多個泛型類型如 class Test<T,U>...以逗號分隔{ PRivate T t; //T代表某一個類型 ... public static <U> U getSomthing() //泛型方法,可以在泛型類中,也可以在普通類中。 { ... }}

調用時:new Test<String>().<String>getSomthing(); //第2個對方法的泛型具體化時要放在方法名的前面。在編譯器可以根據參數自動確定方法使用的U代表哪種類型時,方法名前的<String>可以省略

2.限定泛型的類型。 例如:public static <T extends Comparable> T min(T[] a){...} //只有實現了Comparable接口的類才可以替換T 也可以限定多個類型:<T extends Comparable & Serializable> 使用&分隔 注意:無論限定為接口還是類,一律使用extends。另外,限定的最多只能有一個類,可以有多個接口,并且,類在<>中的順序放在第一個。

3.泛型代碼和虛擬機 擦除:將具體類型替換為Object類型(沒有限定泛型類型時)或者是限定泛型類型的第一個類型,例如2中的第2個代碼,將會替換為Comparable類型。 擦除之后的類型成為原始類型。

4.使用泛型時需要考慮的限制 (1)不能用基本類型實例化類型參數。例如,不能<double>,可以<Double> (2)運行時類型都會被擦除為原始類型。所以: [1]不能使用 a instanceof Pair<String>只能夠使用 a instanceof Pair 或者 a instanceof Pair<?>。也就是說,instanceof對于泛型類只能夠判斷a是否是任意類型的一個Pair對象。 [2]對于泛型類,getClass方法也只會返回原始類型。如:Pair<String> stringPair=...; Pair<Employee> employeePair=...; 此時,stringPair.getClass()==employeePair.getClass()會返回true,因為getClass方法返回的都是Pair.class [3]也不能進行強制類型轉換,例如 Pair<String> p = (Pair<String>) a (3)不能實例化參數化類型的數組。例如:Pair<String>[] table = new Pair<String>[10]; 注意:只是不能實例化(new Pair<String>[10]),但是可以聲明(Pair<String>[] table) (4)對于參數可變的方法,可以向方法中傳入多個泛型類型的實例(實際上會將這幾個泛型實例放在一個數組中,但是這里限制有所放松,只會給出警告),例如:

public static <T> void addAll(Collection<T> coll, T... t) //這里的t實際上是一個數組,會給出警告。但是可以使用@SuppressWarnings(unchecked)抑制警告或者@SafeVarargs接觸限制。{ ...}

但是,會隱藏著危險:

Pair<String>[] table = ...; Object[] objarray = table; objarray[0] = new Pair<Employee>(); //將一個Pair<Employee>類型的對象插入到Pair<String>類型的數組中。能夠順利運行并且沒有異常,但是在使用table[0]時,會在別處得到一個異常。

(5)不能實例化類型變量,像 new T(…), new T[…], T.class都不可以使用 (6)不能在靜態域或者靜態方法中引用類型變量。例如 private static T singleInstance;(不允許有T) (7)既不能拋出也不能捕獲泛型類對象,甚至泛型類 擴展 Throwable類都是不合法的。 例如:

public class Problem<T> extends Exception{...} //這樣不可以但是下面這樣是可以的:public static <T extends Throwable> void doWork(T t) throws T {} //合法

另外,java異常處理的原則是必須為所有的已檢查異常提供一個處理器,然而可以利用<T extends Throwable>消除編譯器對已檢查異常的檢查,對于如何去做,這里不詳細描述。 (8)要想支持擦除的轉換,就需要強制限制一個類或者類型變量不能同時成為兩個接口類型的子類,而這兩個接口是同一接口的不同參數化。例如,下面代碼是非法的

class Calendar implements Comparable<Calendar>{...}class GregorianCalendar extends Calendar implements Comparable<GregorianCalendar>{...} //Error

5.泛型類型的繼承規則 (1)Employee是Manager的超類,然而Pair<Manager>并不是Pair<Employee>類的子類,他們之間沒有任何關系。也不能用一個Pair<Employee>變量引用一個Pair<Manager>對象。 (2)永遠可以將參數化類型轉換為一個原始類型。例如,Pair<Employee>是原始類型Pair的一個子類型。

Pair<Manager> managerBuddies = new Pair<>{ceo, cfo}; //new的對象中的<>可以像這樣不寫Manager,這樣managerBuddies中的T也是自動變成ManagerPair rawBuddies = managerBuddies; //完全可以rawBuddies.setFirst(new File("...")); //編譯器只會產生一個警告,但是運行時會拋出異常。

(3)泛型類可以擴展實現其他的泛型類。例如,ArrayList<T>實現List<T>接口。這意味著,一個ArrayList<Manager>可以被轉換為一個List<Manager>

6.通配符類型(帶有子類型限定的通配符可以從泛型對象讀取,帶有超類型限定的通配符可以向泛型對象寫入) (1)通配符的子類型限定 Pair<Manager>Pair<Employee> 都是Pair<? extends Employee>的子類型。因此,可以用Pair<? extends Employee>類型的變量引用Pair<Manager>類型的對象。例如,

Pair<? extends Employee> p = new Pair<Manager>(...); //沒毛病Employee first = p.getFirst(); //沒毛病p.setFirst(...); //有毛病,p的setFirst方法不允許接收任何類型的參數,因為?無法與任何類型匹配,不知道到底是哪個類型。

(2)通配符的超類型的限定 [1]像Pair<? super Manager>通配符限制為Manager的超類型(不包括Manager)。此時Pair<Employee>和Pair<Object>都是Pair<? super Manager>的 子類。 [2]可以使用set方法,但是不可以使用get方法,也就是說與(1)相反:

Pair<? super Manager> p = new Pair<Employee>(...); //沒毛病 Employee first = p.getFirst(); //有毛病 p.setFirst(...); //沒毛病

(3)可以使用<T extends Comparable<? super T> >替換<T extends Comparable<T> > , 因為后一種情況有時會出問題,例如當T為GregorianCalandar時,由于GregorianCalendar并親自沒有實現compareTo方法,而是從Calendar繼承來的。所以GregorianCalendar實現的是Comparable<Calendar>,而不是Comparable<GregorianCalendar>,所以會出問題。 (4)無限定通配符Pair<?>, 使用getFirst方法只能返回給一個Object變量,setFirst方法不能被調用。(但是可以setFirst(null)) *沒看懂到底有什么用 (5)通配符的捕獲 如交換Pair對象的兩個數據成員first和second

public static void swap(Pair<?> p) //假設要求必須用Pair<?>類型的參數{ swapHelper(p); //這里swapHelper中的Pair<T>就捕獲到了swap函數中的Pair<?>類型的對象}public static <T> void swapHelper(Pair<T> p){ T t = p.getFirst(); p.setFirst(p.getSecond()); p.setSecond(t);}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 嘉义市| 翼城县| 钟祥市| 姜堰市| 尉犁县| 彰化县| 搜索| 北海市| 武冈市| 鄢陵县| 庄河市| 江门市| 广安市| 乐平市| 肇源县| 万载县| 万山特区| 花莲市| 贵定县| 红安县| 响水县| 宁晋县| 五指山市| 张家界市| 镇康县| 安溪县| 前郭尔| 南通市| 吉木萨尔县| 万载县| 郑州市| 托里县| 阳高县| 恩施市| 濉溪县| 台安县| 水城县| 德化县| 上林县| 鸡西市| 彭泽县|