Java程序設(shè)計與實踐(微課版)-課件13 泛型程序設(shè)計(含spoc)_第1頁
Java程序設(shè)計與實踐(微課版)-課件13 泛型程序設(shè)計(含spoc)_第2頁
Java程序設(shè)計與實踐(微課版)-課件13 泛型程序設(shè)計(含spoc)_第3頁
Java程序設(shè)計與實踐(微課版)-課件13 泛型程序設(shè)計(含spoc)_第4頁
Java程序設(shè)計與實踐(微課版)-課件13 泛型程序設(shè)計(含spoc)_第5頁
已閱讀5頁,還剩28頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

泛型程序設(shè)計主講人:鄭如濱總目錄泛型簡介泛型方法與類型變量泛型代碼和虛擬機(jī)使用泛型的約束與局限性泛型類型的繼承規(guī)則通配符類型我們以前編寫的程序已經(jīng)使用過泛型List<Employee>aList=newArrayList<Employee>();List<String>bList=newArrayList<String>();bList.add("abc");思考如果讓你實現(xiàn)ArrayList,需要分別針對Employee與String編寫兩套代碼嗎?代碼分析:ArrayList的add方法publicbooleanadd(Ee){………elementData[size++]=e;//elementData為Object[]類型}1.泛型簡介泛型程序設(shè)計編寫的代碼可被不同類型的對象所重用C++通過模板技術(shù)可以指定集合的元素類型,而Java在1.5之前一直沒有相對應(yīng)的功能泛型簡介Java中一個集合可以放任何類型的對象,因為任何對象都is-a

Object但從集合里面獲取對象時必須進(jìn)行強(qiáng)制類型轉(zhuǎn)換ListstrList=newArrayList();strList.add("IamaString!");Stringstr=(String)strList.get(0);不使用泛型的問題強(qiáng)制類型轉(zhuǎn)換存在什么問題?可能會帶來什么錯誤?ListstrList=newArrayList();strList.add("1");Integer

x=(Integer)strList.get(0);System.out.println(x):上面這段代碼編譯錯誤編譯成功,輸出1編譯成功,運(yùn)行時產(chǎn)生ClassCastException編譯成功,運(yùn)行時產(chǎn)生IndexOutOfBoundsExceptionABCD提交可為此題添加文本、圖片、公式等解析,且需將內(nèi)容全部放在本區(qū)域內(nèi)。正常使用需3.0以上版本將String強(qiáng)制轉(zhuǎn)化為Integer會產(chǎn)生ClassCastException答案解析單選題1分答案解析引入泛型的好處泛型允許指定集合中元素的類型,這就可以得到強(qiáng)類型,在編譯時進(jìn)行類型檢查。List<String>strList=newArrayList<>();strList.add("Iamastring");strList.add(newInteger(1));//編譯時報錯,避免運(yùn)行時出錯好處無需使用有風(fēng)險的強(qiáng)制類型轉(zhuǎn)換錯誤在編譯階段就能發(fā)現(xiàn),而不用等到運(yùn)行時才發(fā)現(xiàn)出錯類型參數(shù)Java7中的菱形語法Java7以前List<String>strList=newArrayList<String>();Java7以后可以使用菱形語法List<String>strList=newArrayList<>();原理:通過變量類型推斷出創(chuàng)建的泛型類的類型即,通過List<String>推斷出后面的ArrayList必然是ArrayList<String>學(xué)習(xí)泛型需要達(dá)到什么程度?(略)泛型程序設(shè)計分為3個熟練級別基本級:僅僅會使用泛型類,比如ArrayList<String>熟練使用泛型類當(dāng)把不同泛型類混合在一起,可能會碰到問題(也許歷史遺留問題),能系統(tǒng)地解決問題。能看懂使用泛型技術(shù)編寫的代碼。熟練實現(xiàn)自己的泛型類和泛型方法達(dá)到該級別后,你之所以寫這些代碼,是為了讓更多人復(fù)用這些代碼簡單泛型類的定義publicclassPair<T>{privateTfirst;

privateTsecond;publicPair(Tfirst,Tsecond){

this.first=first;

this.second=second;

}publicTgetFirst(){returnfirst;}publicvoidsetFirst(TnewValue){first=newValue;}....}思考:這里需要T的類型信息嗎?泛型類可看做普通類的工廠如何使用:詳見Pair.java與PairTest1.java類型參數(shù)2.泛型方法與類型變量限定在普通的類中也可以定義一個泛型方法classArrayAlg{publicstatic<T>T

getMiddle(T[]arr){returnarr[arr.length/2];}}//聲明為ObjectgetMiddle(Object[]arr)有何缺點(diǎn)?使用Integer[]ints={0,1,2,3,4,5,6,7,8,9};Integerx=ArrayAlg.getMiddle(ints);討論:為什么不聲明為Object

getMiddle(Object[]arr)?2.泛型方法與類型變量限定下列代碼實現(xiàn)了什么功能?publicclassArrayAlg{publicstatic<T>Tmin(T[]a){

Tsmallest=a[0];

for(inti=1;i<a.length;i++){if((pareTo(a[i])>0))//什么問題?smallest=a[i];}returnsmallest;}}改進(jìn)publicstatic<TextendsComparable>Tmin(T[]a)類型變量限定另一個例子代碼:PairTest2.javapublicstatic<TextendsComparable>Pair<T>minmax(T[]a){......}TextendsComparable表示T是綁定類型(Comparable)的子類型可有多個綁定類型TextendsComparable&Serializable3.泛型與虛擬機(jī)虛擬機(jī)內(nèi)沒有泛型的類型信息,所有的對象都是普通類!Pair<T>的原始類型(rawtype)如下publicclassPair{publicPair(Objectfirst,Objectsecond){.....}}類型擦除:編譯時將擦除類型參數(shù)信息。如,將T替換為Object因為T是無限定類型變量,所以用Object替換實際上泛型類就是一個普通類!!!泛型的原始類型(rawtype)原始類型定義沒有任何類型參數(shù)的泛型接口或泛型類實際上,對同一泛型類,給定不同的參數(shù)類型,只存在一個原始類型。例子Pair是Pair<String>與Pair<Integer>的原始類型List是List<String>與List<…>的原始類型泛型的本質(zhì)Java中泛型的本質(zhì)泛型僅是一個編譯器現(xiàn)象!虛擬機(jī)中沒有泛型,只有普通的類和方法運(yùn)行過程中并沒有類型參數(shù)T泛型表達(dá)式的轉(zhuǎn)換Pair<Employee>buddies=...;Employeebuddy=buddies.getFirst();getFirst返回什么類型?實際上是Object類型,編譯器自動插入(Employee)buddies.getFirst()進(jìn)行強(qiáng)制類型轉(zhuǎn)換。上述代碼在編譯時轉(zhuǎn)換成如下兩條指令調(diào)用方法getFirst,返回Object類型對象將Object類型對象強(qiáng)制轉(zhuǎn)換為Employee類型3.泛型與虛擬機(jī)(略)原始類型用第一個限定的類型變量替換publicclassInterval<TextendsComparable&Serializable>implementsSerializable{publicInterval(Tfirst,Tsecond){....}}替換為publicclassIntervalimplementsSerializable{publicInterval(Comparablefirst,Comparablesecond){....}}4.使用泛型的約束與局限性1.不能使用基本類型不能使用Pair<double>,只能Pair<Double>解決方法:使用包裝類型替換基本類型2.運(yùn)行時類型查詢只適用于原始類型Pair<String>x=newPair<>();xinstanceofPair<String>//無法編譯通過xinstanceofPair//只能查詢原始類型Pair<String>與Pair<Employee>的原始類型(rawtype)相同,都是Pair5.泛型類型的繼承規(guī)則Pair<Employee>并不是Pair<Manager>的父類!Pair<Manager>managerBuddies=newPair<>(ceo,cfo);Pair<Employee>employeeBuddies=managerBuddies;//不合法5.泛型類型的繼承規(guī)則6.通配符類型Pair<?extendsEmployee>這里的Pair,它的類型參數(shù)是Employee及者其子類,如Pair<Manager>或Pair<Employee>Pair<?extendsEmployee>x=newPair<Manager>();//合法但Pair<String>不是Pair<?extendsEmployee>的子類printBuddies(Pair<Employee>p)方法不能適用于Pair<Manager>,如何改進(jìn)?printBuddies(Pair<?extendsEmployee>p)6.1子類型限定的通配符(extends)下列聲明正確的?Listlist=newArrayList<String>();List<Object>list=newArrayList<String>();List<String>list=newArrayList<>();List<?extendsObject>list=newArrayList<String>();ABCD提交可為此題添加文本、圖片、公式等解析,且需將內(nèi)容全部放在本區(qū)域內(nèi)。正常使用需3.0以上版本錯誤:B.ArrayList<String>并不是List<Object>的子類型。只能List<Object>list=newArrayList<Object>();正確;:A.這里的list是raw類型,可以指向任意泛型List實現(xiàn)類。C.菱形語法,相當(dāng)于List<String>list=newArrayList<String>();D.List<?extendsObject>list代表list中的元素只要是Object的子類就可以了。答案解析答案解析多選題1分6.1子類型限定的通配符(extends)原則:一般來說,帶有子類型(extends)限定的通配符可以從泛型對象中讀。如,源代碼中的getFirst方法printBuddies(Pair<?extendsEmployee>p){Employeefirst=p.getFirst();//從p中讀System.out.println(first.getName());}p中存放的一定是Employee或其子類對象,這就保證該對象已經(jīng)具有Employee擁有的方法與屬性,如getName()代碼詳見PairTest3.java的printBuddies方法printBuddies(Pair<?extendsEmployee>p)6.2通配符的超類型(super)6.2通配符的超類型有泛型方法定義如下minmaxBonus(Manager[]a,Pair<?superManager>result){if(a==null||a.length==0)return;Managermin=a[0];Managermax=a[0];for(inti=1;i<a.length;i++){if(min.getBonus()>a[i].getBonus())min=a[i];if(max.getBonus()<a[i].getBonus())max=a[i];}result.setFirst(min);result.setSecond(max);}1.該方法功能是什么?2.怎么調(diào)用該方法?Pair<Manager>pairManager;Pair<Employee>pairEmployee;Pair<Object>pairObject;使用minmaxBonus(managers,pairManager)minmaxBonus(managers,pairEmployee)minmaxBonus(managers,pairObject)均可調(diào)用6.2通配符的超類型原則:帶有超類型(super)限定的通配符可以向泛型對象寫Pair<?superManager>result;……result.setFirst相當(dāng)于向result中寫入原理Pair<?superManager>result;意味著result中first與second屬性是Manager類型或者其父類型,那么調(diào)用setFirst,實際上就是讓父類變量first指向子類對象(如Emoplyee,Manager)說明:見PairTest3目錄下的Pair.java6.3無限定通配符Pair<?>//使用?就意味著不需知道是什么類型?getFirst()

getFirst的返回值是Object類型當(dāng)不需知道具體實際類型的時候?很好用booleanhasNulls(Pair<?>p){returnp.getFirst()==null||p.getSecond()==null;}缺點(diǎn):不能使用具體類型的信息。編寫方法max可以返回List中所有元素的最大值。List中的元素必須實現(xiàn)Comparable接口。如何聲明該泛型方法max?<T>Tmax(List<T>list)<TextendsComparable<T>>Tmax(List<?>list)<TextendsComparable<String>>Tmax(List<T>list)<TextendsComparable<T>>Tmax(List<T>list)ABCD提交可為此題添加文本、圖片、公式等解析,且需將內(nèi)容全部放在本區(qū)域內(nèi)。正常使用需3.0以上版本T必須extendsComparable<T>A,無限制,不能保證T有compareTo方法B,編譯可過。但是前面的<TextendsComparable<T>>意味著T應(yīng)該實現(xiàn)Comparable接口,而后面的LIst<?>卻意味著List中的元素可以是任何

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論