Office中國(guó)論壇/Access中國(guó)論壇

 找回密碼
 注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

tag 標(biāo)簽: Freebasic泛型

相關(guān)帖子

版塊 作者 回復(fù)/查看 最后發(fā)表

沒(méi)有相關(guān)內(nèi)容

相關(guān)日志

分享 在FreeBasic中使用集合類(泛型)(第二節(jié))
ganlinlao 2015-5-21 15:03
泛型知識(shí): 一般我們并不需要太多了解泛型,因?yàn)镕reebasic主要是和c一樣,通過(guò)宏來(lái)實(shí)現(xiàn)和泛型類似的功能。一般泛型主要是應(yīng)用在集合類中。但在這里還是有必要適度了解一下泛型的概念,以便于以后在進(jìn)行類的封裝時(shí),適度使用泛型會(huì)帶來(lái)更多的方面。 (注:vba中沒(méi)有泛型的概念,因?yàn)閂BA中有一個(gè)萬(wàn)能而讓人痛苦不堪的Variant類型) ************************************************************ 以下內(nèi)容是java的泛型基礎(chǔ) ************************************************************ 1、什么是泛型? 泛型是指在定義類或者接口的時(shí)候可以為類和接口指定類型形參,在定義變量、定義方法是該類型形參可以當(dāng)做普通的類型來(lái)使用,并且該類型形參在定義變量和創(chuàng)建對(duì)象的確定。它的本質(zhì)是參數(shù)化類型,也就是說(shuō)所操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù)。這種參數(shù)類型可以用在類、接口和方法的創(chuàng)建中,分別稱為泛型類、泛型接口、泛型方法。 Java語(yǔ)言引入泛型的好處是安全簡(jiǎn)單。 在引入泛型之前,Java類型分為原始類型、復(fù)雜類型,其中復(fù)雜類型分為數(shù)組和類。引入泛型后,一個(gè)復(fù)雜類型就可以在細(xì)分成更多的類型。 例如原先的類型List,現(xiàn)在在細(xì)分成ListObject, ListString等更多的類型。 注意,現(xiàn)在ListObject, ListString是兩種不同的類型, 他們之間沒(méi)有繼承關(guān)系,即使String繼承了Object。下面的代碼是非法的 ListString ls = new ArrayListString(); ListObject lo = ls; 這樣設(shè)計(jì)的原因在于,根據(jù)lo的聲明,編譯器允許你向lo中添加任意對(duì)象(例如Integer),但是此對(duì)象是 ListString,破壞了數(shù)據(jù)類型的完整性。 在引入泛型之前,要在類中的方法支持多個(gè)數(shù)據(jù)類型,就需要對(duì)方法進(jìn)行重載,在引入泛型后,可以解決此問(wèn)題 (多態(tài)),更進(jìn)一步可以定義多個(gè)參數(shù)以及返回值之間的關(guān)系。 例如 public void write(Integer i, Integer da); 的泛型版本為 public T void write(T t, T iListArray; new ArrayListInteger ;//編譯時(shí)錯(cuò)誤 5. 實(shí)現(xiàn)原理 5.1. Java泛型時(shí)編譯時(shí)技術(shù),在運(yùn)行時(shí)不包含泛型信息,僅僅Class的實(shí)例中包含了類型參數(shù)的定義信息。 泛型是通過(guò)java編譯器的稱為擦除(erasure)的前端處理來(lái)實(shí)現(xiàn)的。你可以(基本上就是)把它認(rèn)為是一個(gè)從源 碼到源碼的轉(zhuǎn)換,它把泛型版本轉(zhuǎn)換成非泛型版本。 基本上,擦除去掉了所有的泛型類型信息。所有在尖括號(hào)之間的類型信息都被扔掉了,因此,比如說(shuō)一個(gè) ListString類型被轉(zhuǎn)換為L(zhǎng)ist。所有對(duì)類型變量的引用被替換成類型變量的上限(通常是Object)。而且, 無(wú)論何時(shí)結(jié)果代碼類型不正確,會(huì)插入一個(gè)到合適類型的轉(zhuǎn)換。 T T badCast(T t, Object o) { return (T) o; // unchecked warning } 類型參數(shù)在運(yùn)行時(shí)并不存在。這意味著它們不會(huì)添加任何的時(shí)間或者空間上的負(fù)擔(dān),這很好。不幸的是,這也意味 著你不能依靠他們進(jìn)行類型轉(zhuǎn)換。 5.2.一個(gè)泛型類被其所有調(diào)用共享 下面的代碼打印的結(jié)果是什么? ListString l1 = new ArrayListString(); ListInteger l2 = new ArrayListInteger(); System.out.println(l1.getClass() == l2.getClass()); 或許你會(huì)說(shuō)false,但是你想錯(cuò)了。它打印出true。因?yàn)橐粋(gè)泛型類的所有實(shí)例在運(yùn)行時(shí)具有相同的運(yùn)行時(shí)類(class), 而不管他們的實(shí)際類型參數(shù)。 事實(shí)上,泛型之所以叫泛型,就是因?yàn)樗鼘?duì)所有其可能的類型參數(shù),有同樣的行為;同樣的類可以被當(dāng)作許多不同 的類型。作為一個(gè)結(jié)果,類的靜態(tài)變量和方法也在所有的實(shí)例間共享。這就是為什么在靜態(tài)方法或靜態(tài)初始化代碼 中或者在靜態(tài)變量的聲明和初始化時(shí)使用類型參數(shù)(類型參數(shù)是屬于具體實(shí)例的)是不合法的原因。 5.3. 轉(zhuǎn)型和instanceof 泛型類被所有其實(shí)例(instances)共享的,另一個(gè)暗示是檢查一個(gè)實(shí)例是不是一個(gè)特定類型的泛型類是沒(méi)有意義的。 Collection cs = new ArrayListString(); if (cs instanceof CollectionString) { ...} // 非法 類似的,如下的類型轉(zhuǎn)換 CollectionString cstr = (CollectionString) cs; 得到一個(gè)unchecked warning,因?yàn)檫\(yùn)行時(shí)環(huán)境不會(huì)為你作這樣的檢查。 6. Class的泛型處理 Java 5之后,Class變成泛型化了。 JDK1.5中一個(gè)變化是類 java.lang.Class是泛型化的。這是把泛型擴(kuò)展到容器類之外的一個(gè)很有意思的例子。 現(xiàn)在,Class有一個(gè)類型參數(shù)T, 你很可能會(huì)問(wèn),T 代表什么?它代表Class對(duì)象代表的類型。比如說(shuō), String.class類型代表 ClassString,Serializable.class代表 ClassSerializable。 這可以被用來(lái)提高你的反射代碼的類型安全。 特別的,因?yàn)?Class的 newInstance() 方法現(xiàn)在返回一個(gè)T, 你可以在使用反射創(chuàng)建對(duì)象時(shí)得到更精確的類型。 比如說(shuō),假定你要寫(xiě)一個(gè)工具方法來(lái)進(jìn)行一個(gè)數(shù)據(jù)庫(kù)查詢,給定一個(gè)SQL語(yǔ)句,并返回一個(gè)數(shù)據(jù)庫(kù)中符合查詢條件 的對(duì)象集合(collection)。 一個(gè)方法是顯式的傳遞一個(gè)工廠對(duì)象,像下面的代碼: interface FactoryT { public T[] make(); } public T CollectionT select(FactoryT factory, String statement) { CollectionT result = new ArrayListT(); /* run sql query using jdbc */ for ( int i=0; i10; i++ ) { /* iterate over jdbc results */ T item = factory.make(); /* use reflection and set all of item’s fields from sql results */ result.add( item ); } return result; } 你可以這樣調(diào)用: select(new FactoryEmpInfo(){ public EmpInfo make() { return new EmpInfo(); } } , ”selection string”); 也可以聲明一個(gè)類 EmpInfoFactory 來(lái)支持接口 Factory: class EmpInfoFactory implements FactoryEmpInfo { ... public EmpInfo make() { return new EmpInfo();} } 然后調(diào)用: select(getMyEmpInfoFactory(), "selection string"); 這個(gè)解決方案的缺點(diǎn)是它需要下面的二者之一: 調(diào)用處那冗長(zhǎng)的匿名工廠類,或?yàn)槊總(gè)要使用的類型聲明一個(gè)工廠類并傳遞其對(duì)象給調(diào)用的地方 這很不自然。 使用class類型參數(shù)值是非常自然的,它可以被反射使用。沒(méi)有泛型的代碼可能是: Collection emps = sqlUtility.select(EmpInfo.class, ”select * from emps”); ... public static Collection select(Class c, String sqlStatement) { Collection result = new ArrayList(); /* run sql query using jdbc */ for ( /* iterate over jdbc results */ ) { Object item = c.newInstance(); /* use reflection and set all of item’s fields from sql results */ result.add(item); } return result; } 但是這不能給我們返回一個(gè)我們要的精確類型的集合。現(xiàn)在Class是泛型的,我們可以寫(xiě): CollectionEmpInfo emps=sqlUtility.select(EmpInfo.class, ”select * from emps”); ... public static T CollectionT select(ClassTc, String sqlStatement) { CollectionT result = new ArrayListT(); /* run sql query using jdbc */ for ( /* iterate over jdbc results */ ) { T item = c.newInstance(); /* use reflection and set all of item’s fields from sql results */ result.add(item); } return result; } 來(lái)通過(guò)一種類型安全的方式得到我們要的集合。 這項(xiàng)技術(shù)是一個(gè)非常有用的技巧,它已成為一個(gè)在處理注釋(annotations)的新API中被廣泛使用的習(xí)慣用法。 **************************************************************** 以上內(nèi)容是java的泛型基礎(chǔ) *************************************************************** 如果依然對(duì)泛型的概念不是很了解的話,可參看c#的泛型概念
個(gè)人分類: FreeBasic|1912 次閱讀|0 個(gè)評(píng)論

QQ|站長(zhǎng)郵箱|小黑屋|手機(jī)版|Office中國(guó)/Access中國(guó) ( 粵ICP備10043721號(hào)-1 )  

GMT+8, 2025-7-17 03:28 , Processed in 0.057593 second(s), 13 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

返回頂部