在日常的學(xué)習(xí)、工作、生活中,肯定對(duì)各類(lèi)范文都很熟悉吧。范文怎么寫(xiě)才能發(fā)揮它最大的作用呢?以下是小編為大家收集的優(yōu)秀范文,歡迎大家分享閱讀。
java泛型實(shí)現(xiàn)篇一
package test7;
import ist;
class student
{
int number;
string name;
string cla;
public int getnumber()
{
return number;
}
public void setnumber(int number)
{
thi = number;
}
public string getname()
{
return name;
}
public void setname(string name)
{
= name;
}
public string getcla()
{
return cla;
}
public void setcla(string cla)
{
thi = cla;
}
public student(){}
public student(int number,string name,string cla)
{
thi = number;
= name;
thi = cla;
}
}
public class test071 {
public static void main(string[] args) {
n("設(shè)計(jì)者:");
student s1 = new student(123, "張三", "11計(jì)科");
student s2 = new student(124, "李四", "11計(jì)科");
student s3 = new student(125, "王五", "11計(jì)科");
student dujingjing = new student(20110105,"杜","11計(jì)科");
arraylist al = new arraylist();
(s1);
(s2);
(s3);
(dujingjing);
for(int i = 0;i<();i++)
{
student s = (student)(i);
n("學(xué)號(hào):" + + " 姓名:" ++ " 班級(jí):" +);
}
}
}
簡(jiǎn)單泛型實(shí)例
java中泛型定義
java的泛型類(lèi)就是一個(gè)用類(lèi)型作為參數(shù)的類(lèi),即帶有參數(shù)化類(lèi)型的類(lèi)。就像我們定義類(lèi)的成員方法一樣。大家很熟悉java的成員方法形式是method(string str,int i),方法中參數(shù)str、i的值是可變的。而泛型也是一樣的:class泛型類(lèi)類(lèi)名,這里的k和v就像方法中的參數(shù)str和i,也是可變的。
class uset{
private t x;
public setx(t x){````````}
}
package test7;
泛型類(lèi):l2
class l2
{
private t obj;
public l2(t obj)
{
= obj;
}
public t getobj()
{
return ;
}
public void setobj(t obj)
{
= obj;
}
public void showobj(t obj)
{
n("數(shù)據(jù)為:" + ); }
}
主類(lèi):
public class test072 {
public static void main(string[] args) {
n("設(shè)計(jì)者:");
l2name = new l2("汽車(chē)"); j(());
l2data = new l2(12); j(());
}
}
簡(jiǎn)單集合類(lèi)
java泛型實(shí)現(xiàn)篇二
1. 什么是泛型?
泛型(generic type 或者 generics)是對(duì) java 語(yǔ)言的類(lèi)型系統(tǒng)的一種擴(kuò)展,以支持創(chuàng)建可以按類(lèi)型進(jìn)行參數(shù)化的類(lèi)??梢园杨?lèi)型參數(shù)看作是使用參數(shù)化類(lèi)型時(shí)指定的類(lèi)型的一個(gè)占位符,就像方法的形式參數(shù)是運(yùn)行時(shí)傳遞的值的占位符一樣。
可以在集合框架(collection framework)中看到泛型的動(dòng)機(jī)。例如,map 類(lèi)允許您向一個(gè) map 添加任意類(lèi)的對(duì)象,即使最常見(jiàn)的情況是在給定映射(map)中保存某個(gè)特定類(lèi)型(比如 string)的對(duì)象。
因?yàn)?() 被定義為返回 object,所以一般必須將 () 的結(jié)果強(qiáng)制類(lèi)型轉(zhuǎn)換為期望的類(lèi)型,如下面的代碼所示:
map m = new hashmap();
("key", "blarg");
string s = (string) ("key");
要讓程序通過(guò)編譯,必須將 get() 的結(jié)果強(qiáng)制類(lèi)型轉(zhuǎn)換為 string,并且希望結(jié)果真的是一個(gè) string。但是有可能某人已經(jīng)在該映射中保存了不是 string 的東西,這樣的話,上面的代碼將會(huì)拋出 classcastexception。
理想情況下,您可能會(huì)得出這樣一個(gè)觀點(diǎn),即 m 是一個(gè) map,它將 string 鍵映射到 string 值。這可以讓您消除代碼中的強(qiáng)制類(lèi)型轉(zhuǎn)換,同時(shí)獲得一個(gè)附加的類(lèi)型檢查層,該檢查層可以防止有人將錯(cuò)誤類(lèi)型的鍵或值保存在集合中。這就是泛型所做的工作。
2. 泛型的好處
java 語(yǔ)言中引入泛型是一個(gè)較大的功能增強(qiáng)。不僅語(yǔ)言、類(lèi)型系統(tǒng)和編譯器有了較大的變化,以支持泛型,而且類(lèi)庫(kù)也進(jìn)行了大翻修,所以許多重要的類(lèi),比如集合框架,都已經(jīng)成為泛型化的了。這帶來(lái)了很多好處:
類(lèi)型安全。 泛型的主要目標(biāo)是提高 java 程序的類(lèi)型安全。通過(guò)知道使用泛型定義的變量的類(lèi)型限制,編譯器可以在一個(gè)高得多的程度上驗(yàn)證類(lèi)型假設(shè)。沒(méi)有泛型,這些假設(shè)就只存在于程序員的頭腦中(或者如果幸運(yùn)的話,還存在于代碼注釋中)。
java 程序中的一種流行技術(shù)是定義這樣的集合,即它的元素或鍵是公共類(lèi)型的,比如“string 列表”或者“string 到 string 的映射”。通過(guò)在變量聲明中捕獲這一附加的類(lèi)型信息,泛型允許編譯器實(shí)施這些附加的類(lèi)型約束。類(lèi)型錯(cuò)誤現(xiàn)在就可以在編譯時(shí)被捕獲了,而不是在運(yùn)行時(shí)當(dāng)作 classcastexception 展示出來(lái)。將類(lèi)型檢查從運(yùn)行時(shí)挪到編譯時(shí)有助于您更容易找到錯(cuò)誤,并可提高程序的可靠性。
消除強(qiáng)制類(lèi)型轉(zhuǎn)換。 泛型的一個(gè)附帶好處是,消除源代碼中的許多強(qiáng)制類(lèi)型轉(zhuǎn)換。這使得代碼更加可讀,并且減少了出錯(cuò)機(jī)會(huì)。
盡管減少?gòu)?qiáng)制類(lèi)型轉(zhuǎn)換可以降低使用泛型類(lèi)的代碼的羅嗦程度,但是聲明泛型變量會(huì)帶來(lái)相應(yīng)的羅嗦。比較下面兩個(gè)代碼例子。
該代碼不使用泛型:
list li = new arraylist();
(new integer(3));
integer i = (integer) (0);
該代碼使用泛型:
listli = new arraylist();
(new integer(3));
integer i = (0);
在簡(jiǎn)單的程序中使用一次泛型變量不會(huì)降低羅嗦程度。但是對(duì)于多次使用泛型變量的大型程序來(lái)說(shuō),則可以累積起來(lái)降低羅嗦程度。
潛在的性能收益。 泛型為較大的優(yōu)化帶來(lái)可能。在泛型的初始實(shí)現(xiàn)中,編譯器將強(qiáng)制類(lèi)型轉(zhuǎn)換(沒(méi)有泛型的話,程序員會(huì)指定這些強(qiáng)制類(lèi)型轉(zhuǎn)換)插入生成的字節(jié)碼中。但是更多類(lèi)型信息可用于編譯器這一事實(shí),為未來(lái)版本的 jvm 的優(yōu)化帶來(lái)可能。
由于泛型的實(shí)現(xiàn)方式,支持泛型(幾乎)不需要 jvm 或類(lèi)文件更改。所有工作都在編譯器中完成,編譯器生成類(lèi)似于沒(méi)有泛型(和強(qiáng)制類(lèi)型轉(zhuǎn)換)時(shí)所寫(xiě)的代碼,只是更能確保類(lèi)型安全而已。
3. 泛型用法的例子
泛型的許多最佳例子都來(lái)自集合框架,因?yàn)榉盒妥屇诒4嬖诩现械脑厣现付?lèi)型約束??紤]這個(gè)使用 map 類(lèi)的例子,其中涉及一定程度的優(yōu)化,即 () 返回的結(jié)果將確實(shí)是一個(gè) string:
map m = new hashmap();
("key", "blarg");
string s = (string) ("key");
如果有人已經(jīng)在映射中放置了不是 string 的其他東西,上面的代碼將會(huì)拋出 classcastexception。泛型允許您表達(dá)這樣的類(lèi)型約束,即 m 是一個(gè)將 string 鍵映射到 string 值的 map。這可以消除代碼中的強(qiáng)制類(lèi)型轉(zhuǎn)換,同時(shí)獲得一個(gè)附加的類(lèi)型檢查層,這個(gè)檢查層可以防止有人將錯(cuò)誤類(lèi)型的鍵或值保存在集合中。
下面的代碼示例展示了 jdk 5.0 中集合框架中的 map 接口的定義的一部分:
public interface map{
public void put(k key, v value);
public v get(k key);
}
注意該接口的兩個(gè)附加物:
類(lèi)型參數(shù) k 和 v 在類(lèi)級(jí)別的規(guī)格說(shuō)明,表示在聲明一個(gè) map 類(lèi)型的變量時(shí)指定的類(lèi)型的占位符。
在 get()、put() 和其他方法的方法簽名中使用的 k 和 v。
為了贏得使用泛型的好處,必須在定義或?qū)嵗?map 類(lèi)型的變量時(shí)為 k 和 v 提供具體的值。以一種相對(duì)直觀的方式做這件事:
mapm = new hashmap();
("key", "blarg");
string s = ("key");
當(dāng)使用 map 的泛型化版本時(shí),您不再需要將 () 的結(jié)果強(qiáng)制類(lèi)型轉(zhuǎn)換為 string,因?yàn)榫幾g器知道 get() 將返回一個(gè) string。
在使用泛型的版本中并沒(méi)有減少鍵盤(pán)錄入;實(shí)際上,比使用強(qiáng)制類(lèi)型轉(zhuǎn)換的版本需要做更多鍵入。使用泛型只是帶來(lái)了附加的類(lèi)型安全。因?yàn)榫幾g器知道關(guān)于您將放進(jìn) map 中的鍵和值的類(lèi)型的更多信息,所以類(lèi)型檢查從執(zhí)行時(shí)挪到了編譯時(shí),這會(huì)提高可靠性并加快開(kāi)發(fā)速度。
向后兼容
在 java 語(yǔ)言中引入泛型的一個(gè)重要目標(biāo)就是維護(hù)向后兼容。盡管 jdk 5.0 的標(biāo)準(zhǔn)類(lèi)庫(kù)中的許多類(lèi),比如集合框架,都已經(jīng)泛型化了,但是使用集合類(lèi)(比如 hashmap 和 arraylist)的現(xiàn)有代碼將繼續(xù)不加修改地在 jdk 5.0 中工作。當(dāng)然,沒(méi)有利用泛型的現(xiàn)有代碼將不會(huì)贏得泛型的類(lèi)型安全好處。
4. 泛型基礎(chǔ)
4.1 類(lèi)型參數(shù)
在定義泛型類(lèi)或聲明泛型類(lèi)的變量時(shí),使用尖括號(hào)來(lái)指定形式類(lèi)型參數(shù)。形式類(lèi)型參數(shù)與實(shí)際類(lèi)型參數(shù)之間的關(guān)系類(lèi)似于形式方法參數(shù)與實(shí)際方法參數(shù)之間的關(guān)系,只是類(lèi)型參數(shù)表示類(lèi)型,而不是表示值。
泛型類(lèi)中的類(lèi)型參數(shù)幾乎可以用于任何可以使用類(lèi)名的地方。例如,下面是 接口的定義的摘錄:
public interface map{
public void put(k key, v value);
public v get(k key);
}
map 接口是由兩個(gè)類(lèi)型參數(shù)化的,這兩個(gè)類(lèi)型是鍵類(lèi)型 k 和值類(lèi)型 v。(不使用泛型)將會(huì)接受或返回 object 的方法現(xiàn)在在它們的方法簽名中使用 k 或 v,指示附加的類(lèi)型約束位于 map 的規(guī)格說(shuō)明之下。
當(dāng)聲明或者實(shí)例化一個(gè)泛型的對(duì)象時(shí),必須指定類(lèi)型參數(shù)的值:
mapmap = new ha
shmap();
注意,在本例中,必須指定兩次類(lèi)型參數(shù)。一次是在聲明變量 map 的類(lèi)型時(shí),另一次是在選擇 hashmap 類(lèi)的參數(shù)化以便可以實(shí)例化正確類(lèi)型的一個(gè)實(shí)例時(shí)。
編譯器在遇到一個(gè) map類(lèi)型的變量時(shí),知道 k 和 v 現(xiàn)在被綁定為 string,因此它知道在這樣的變量上調(diào)用 () 將會(huì)得到 string 類(lèi)型。
除了異常類(lèi)型、枚舉或匿名內(nèi)部類(lèi)以外,任何類(lèi)都可以具有類(lèi)型參數(shù)。
4.2 命名類(lèi)型參數(shù)
推薦的命名約定是使用大寫(xiě)的單個(gè)字母名稱(chēng)作為類(lèi)型參數(shù)。這與 c++ 約定有所不同(參閱 附錄 a:與 c++ 模板的比較),并反映了大多數(shù)泛型類(lèi)將具有少量類(lèi)型參數(shù)的假定。對(duì)于常見(jiàn)的泛型模式,推薦的名稱(chēng)是:
k —— 鍵,比如映射的鍵。
v —— 值,比如 list 和 set 的內(nèi)容,或者 map 中的值。
e —— 異常類(lèi)。
t —— 泛型。
4.3 泛型不是協(xié)變的
關(guān)于泛型的混淆,一個(gè)常見(jiàn)的來(lái)源就是假設(shè)它們像數(shù)組一樣是協(xié)變的。其實(shí)它們不是協(xié)變的。list
不是 list的父類(lèi)型。
如果 a 擴(kuò)展 b,那么 a 的數(shù)組也是 b 的數(shù)組,并且完全可以在需要 b[] 的地方使用 a[]:
integer[] intarray = new integer[10];
number[] numberarray = intarray;
上面的代碼是有效的,因?yàn)橐粋€(gè) integer 是一個(gè) number,因而一個(gè) integer 數(shù)組是 一個(gè) number 數(shù)組。但是對(duì)于泛型來(lái)說(shuō)則不然。下面的代碼是無(wú)效的:
listintlist = new arraylist();
listnumberlist = intlist; // invalid
最初,大多數(shù) java 程序員覺(jué)得這缺少協(xié)變很煩人,或者甚至是“壞的(broken)”,但是之所以這樣有一個(gè)很好的原因。如果可以將 list賦給 list,下面的代碼就會(huì)違背泛型應(yīng)該提供的類(lèi)型安全:
listintlist = new arraylist();
listnumberlist = intlist; // invalid
(new float(3.1415));
因?yàn)?intlist 和 numberlist 都是有別名的,如果允許的話,上面的代碼就會(huì)讓您將不是 integers 的東西放進(jìn) intlist 中。但是,正如下一屏將會(huì)看到的,您有一個(gè)更加靈活的方式來(lái)定義泛型。
4.4 類(lèi)型通配符
假設(shè)您具有該方法:
void printlist(list l) {
for (object o : l)
n(o);
}
上面的代碼在 jdk 5.0 上編譯通過(guò),但是如果試圖用 list調(diào)用它,則會(huì)得到警告。出現(xiàn)警告是因?yàn)?,您將泛型(list)傳遞給一個(gè)只承諾將它當(dāng)作 list(所謂的原始類(lèi)型)的方法,這將破壞使用泛型的類(lèi)型安全。
如果試圖編寫(xiě)像下面這樣的方法,那么將會(huì)怎么樣?
void printlist(list
l) {
for (object o : l)
n(o);
}
它仍然不會(huì)通過(guò)編譯,因?yàn)橐粋€(gè) list不是 一個(gè) list
(正如前一屏 泛型不是協(xié)變的 中所學(xué)的)。這才真正煩人 —— 現(xiàn)在您的泛型版本還沒(méi)有普通的非泛型版本有用!
解決方案是使用類(lèi)型通配符:
void printlist(list l) {
for (object o : l)
n(o);
}
上面代碼中的問(wèn)號(hào)是一個(gè)類(lèi)型通配符。它讀作“問(wèn)號(hào)”。list 是任何泛型 list 的父類(lèi)型,所以您完全可以將 list
、list或 list<list
> 傳遞給 printlist()。
4.5 類(lèi)型通配符的作用類(lèi)型通配符中引入了類(lèi)型通配符,這讓您可以聲明 list 類(lèi)型的變量。您可以對(duì)這樣的 list 做什么呢?非常方便,可以從中檢索元素,但是不能添加元素。原因不是編譯器知道哪些方法修改列表哪些方法不修改列表,而是(大多數(shù))變化的方法比不變化的方法需要更多的類(lèi)型信息。下面的代碼則工作得很好:
listli = new arraylist();
(new integer(42));
list lu = li;
n((0));
為什么該代碼能工作呢?對(duì)于 lu,編譯器一點(diǎn)都不知道 list 的類(lèi)型參數(shù)的值。但是編譯器比較聰明,它可以做一些類(lèi)型推理。在本例中,它推斷未知的類(lèi)型參數(shù)必須擴(kuò)展 object。(這個(gè)特定的推理沒(méi)有太大的跳躍,但是編譯器可以作出一些非常令人佩服的類(lèi)型推理,后面就會(huì)看到(在底層細(xì)節(jié)一節(jié)中)。所以它讓您調(diào)用 () 并推斷返回類(lèi)型為 object。 另一方面,下面的代碼不能工作:
listli = new arraylist();
(new integer(42));
list lu = li;
(new integer(43)); // error
在本例中,對(duì)于 lu,編譯器不能對(duì) list 的類(lèi)型參數(shù)作出足夠嚴(yán)密的推理,以確定將 integer 傳遞給 () 是類(lèi)型安全的。所以編譯器將不允許您這么做。
以免您仍然認(rèn)為編譯器知道哪些方法更改列表的內(nèi)容哪些不更改列表內(nèi)容,請(qǐng)注意下面的代碼將能工作,因?yàn)樗灰蕾?lài)于編譯器必須知道關(guān)于 lu 的類(lèi)型參數(shù)的任何信息:
listli = new arraylist();
(new integer(42));
list lu = li;
();
4.6 泛型方法
(在 類(lèi)型參數(shù) 一節(jié)中)您已經(jīng)看到,通過(guò)在類(lèi)的定義中添加一個(gè)形式類(lèi)型參數(shù)列表,可以將類(lèi)泛型化。方法也可以被泛型化,不管它們定義在其中的類(lèi)是不是泛型化的。
泛型類(lèi)在多個(gè)方法簽名間實(shí)施類(lèi)型約束。在 list中,類(lèi)型參數(shù) v 出現(xiàn)在 get()、add()、contains() 等方法的簽名中。當(dāng)創(chuàng)建一個(gè) map類(lèi)型的變量時(shí),您就在方法之間宣稱(chēng)一個(gè)類(lèi)型約束。您傳遞給 add() 的值將與 get() 返回的值的類(lèi)型相同。
類(lèi)似地,之所以聲明泛型方法,一般是因?yàn)槟胍谠摲椒ǖ亩鄠€(gè)參數(shù)之間宣稱(chēng)一個(gè)類(lèi)型約束。例如,下面代碼中的 ifthenelse() 方法,根據(jù)它的第一個(gè)參數(shù)的布爾值,它將返回第二個(gè)或第三個(gè)參數(shù):
publict ifthenelse(boolean b, t first, t second) {
return b ? first : second;
}
注意,您可以調(diào)用 ifthenelse(),而不用顯式地告訴編譯器,您想要 t 的什么值。編譯器不必顯式地被告知 t 將具有什么值;它只知道這些值都必須相同。編譯器允許您調(diào)用下面的代碼,因?yàn)榫幾g器可以使用類(lèi)型推理來(lái)推斷出,替代 t 的 string 滿足所有的類(lèi)型約束: string s = ifthenelse(b, "a", "b");
類(lèi)似地,您可以調(diào)用:
integer i = ifthenelse(b, new integer(1), new integer(2));
但是,編譯器不允許下面的代碼,因?yàn)闆](méi)有類(lèi)型會(huì)滿足所需的類(lèi)型約束:
string s = ifthenelse(b, "pi", new float(3.14));
為什么您選擇使用泛型方法,而不是將類(lèi)型 t 添加到類(lèi)定義呢?(至少)有兩種情況應(yīng)該這樣做:
當(dāng)泛型方法是靜態(tài)的時(shí),這種情況下不能使用類(lèi)類(lèi)型參數(shù)。
當(dāng) t 上的類(lèi)型約束對(duì)于方法真正是局部的時(shí),這意味著沒(méi)有在相同類(lèi)的另一個(gè)方法簽名中使用相同類(lèi)型 t 的約束。通過(guò)使得泛型方法的類(lèi)型參數(shù)對(duì)于方法是局部的,可以簡(jiǎn)化封閉類(lèi)型的簽名。
4.7 有限制類(lèi)型
在前一屏 泛型方法 的例子中,類(lèi)型參數(shù) v 是無(wú)約束的或無(wú)限制的類(lèi)型。有時(shí)在還沒(méi)有完全指定類(lèi)型參數(shù)時(shí),需要對(duì)類(lèi)型參數(shù)指定附加的約束。
考慮例子 matrix 類(lèi),它使用類(lèi)型參數(shù) v,該參數(shù)由 number 類(lèi)來(lái)限制:
public class matrix{ ... }
編譯器允許您創(chuàng)建 matrix或 matrix類(lèi)型的變量,但是如果您試圖定義
java泛型實(shí)現(xiàn)篇三
java泛型
java泛型是java1.5中引入的新特性,在此之前,java通過(guò)對(duì)類(lèi)型object的引用來(lái)實(shí)現(xiàn)參數(shù)類(lèi)型的“任意化”,特點(diǎn)則是需要進(jìn)行顯示的強(qiáng)制類(lèi)型轉(zhuǎn)換。(而這種顯示的`類(lèi)型轉(zhuǎn)換可能是無(wú)法進(jìn)行的,是錯(cuò)誤的)但編譯器無(wú)法發(fā)現(xiàn)強(qiáng)制類(lèi)型轉(zhuǎn)換可能引起的異常,異常只有在運(yùn)行時(shí)才能出現(xiàn),成為了系統(tǒng)的安全隱患。----------------------------為啥要進(jìn)入泛型這個(gè)概念 泛型的本質(zhì)是參數(shù)化類(lèi)型,及所操作的數(shù)據(jù)類(lèi)型被指定為一個(gè)參數(shù),此參數(shù)類(lèi)型可以用在類(lèi)、接口、和方法的聲明及創(chuàng)建中,分別被稱(chēng)為泛型類(lèi),泛型接口,及泛型方法。 使用注意事項(xiàng):
泛型的類(lèi)型參數(shù)只能是類(lèi)類(lèi)型(包括自定義類(lèi)),但是不能是簡(jiǎn)單類(lèi)型 泛型類(lèi)型參數(shù)可以是多個(gè)
泛型的參數(shù)類(lèi)型還可以是通配符類(lèi)型
沒(méi)有泛型的錯(cuò)誤:
import .*;
public class nogenerictypedemo{
public static void main(string[] args)
{
list names=new arraylist();
("張桑拿");
(new integer(2);
string namefirst=(string)(0);
string namesecond=(string)(1);//astexception異常,而且編譯時(shí)沒(méi)有被發(fā)現(xiàn)
}
有時(shí)候需要使泛型變量能使用任何的類(lèi)型,此時(shí)可以使用通配符”?”否則可能需要編寫(xiě)許多版本的重載函數(shù),使用通配符,使方法printlsit()可以接受各種類(lèi)型的list對(duì)象,否則必須使用重載技術(shù),
public static void printlist(listlist)
{
//輸出集合中的元素
}
java泛型實(shí)現(xiàn)篇四
泛型總結(jié)篇:
1)泛型參數(shù)只能是類(lèi)類(lèi)型
例如:list// 報(bào)錯(cuò)
list// 正確
2)泛型的類(lèi)型參數(shù)可以有多個(gè)!
例如:listlist = new
arraylist();
3)泛型的參數(shù)類(lèi)型可以使用extends,習(xí)慣稱(chēng)“有界類(lèi)型”,
例如:list,person為list的上界
4)泛型可以使用通配符類(lèi)型!“?” 相當(dāng)于“object”類(lèi)型,(注意不可逆) 例如:list //定義成這樣可以添加object類(lèi)型到list里面去 list
; //定義成這樣不可以添加string類(lèi)型到list里面去 list; // 這樣就可以互等了!這樣還可以設(shè)定泛型的上限
5)帶泛型的類(lèi),構(gòu)造方法寫(xiě)法不變,其后不可以加泛型!
例如:class student{
public student(){} // 構(gòu)造方法這樣寫(xiě)就錯(cuò)了
}
6)list不是 list
的子類(lèi)!,不可以把前者看成后者的子類(lèi),所以不
可以把前者的實(shí)例賦給后者
例如: listslist = new arraylist();
(new string("abc"));
list
olist = new arraylist
();
("abc");
olist = slist; // 報(bào)錯(cuò)!
7)帶不同泛型參數(shù)的實(shí)例可以共享類(lèi)的靜態(tài)方法和靜態(tài)變量,所以靜態(tài)方法和靜態(tài)變量
申明的時(shí)候不可以使用類(lèi)型行參
例如:class cup{
static t info; // 報(bào)錯(cuò)!
public static setinfo(t info){}; // 報(bào)錯(cuò)!
}
8)帶不同泛型參數(shù)的類(lèi)是共享一個(gè)字節(jié)碼文件的!反編譯過(guò)后泛型參數(shù)就被擦除了
例如:listslist = new arraylist();
(new string("aaa"));
listilist = new arraylist();
(new integer(100));
n(ss()==ss()); 結(jié)果為true;
9)當(dāng)使用定義了泛型參數(shù)的接口 和 父類(lèi)的時(shí)候!就不能在帶參數(shù)了 例如:class sub extends father{} // 錯(cuò)誤
10)
class t{}
public class typetest extends t{}//報(bào)錯(cuò)
class t{}
public class typetest extends t{} // 正確 可使用string等基本封裝類(lèi)型
class t{}
class student{}
public class typetest extends t{} // 這樣也正確
11) 泛型方法 ,泛型方法的參數(shù)的作用域僅在本方法,要和方法帶泛型區(qū)分開(kāi)! staticvoid test(lists_list){} // 泛型參數(shù)要放在返回類(lèi)型前
12)帶有泛型的代碼轉(zhuǎn)換成沒(méi)有泛型的代碼由javac完成,虛擬機(jī)不處理這些事情!
這種技術(shù)叫做 “擦除”;
例如:class food{
t size;
public food(t size){} //注意構(gòu)造方法不可以帶泛型參數(shù)!
public void setsize(){ = size; }
public t getsize(){ return ;}
}
public class test{
public static void main(string arg[]){
fooda = new food(6);
ingeger as = e(); // 返回的是integer的類(lèi)型 food b = a; //把a(bǔ)對(duì)象賦給food變量;泛型參數(shù)類(lèi)型會(huì)丟失 即擦除;
number size1 = e(); // b只知道size的類(lèi)型是number // integer in = e(); 這樣是編譯錯(cuò)誤的!
} }
java泛型實(shí)現(xiàn)篇五
導(dǎo)讀:本文是從《java generics quick tutorial》這篇文章翻譯而來(lái),譯文來(lái)自外刊it評(píng)論《java泛型簡(jiǎn)明教程》。內(nèi)容如下:
泛型是java se 5.0中引入的一項(xiàng)特征,自從這項(xiàng)語(yǔ)言特征出現(xiàn)多年來(lái),我相信,幾乎所有的java程序員不僅聽(tīng)說(shuō)過(guò),而且使用過(guò)它。關(guān)于java泛型的教程,免費(fèi)的,不免費(fèi)的,有很多。我遇到的最好的教材有:
the java tutorial
java generics and collections, by maurice naftalin and philip wadler
effective java中文版(第2版), by joshua bloch.
盡管有這么多豐富的資料,有時(shí)我感覺(jué),有很多的程序員仍然不太明白java泛型的功能和意義。這就是為什么我想使用一種最簡(jiǎn)單的形式來(lái)總結(jié)一下程序員需要知道的關(guān)于java泛型的最基本的知識(shí)。
java泛型由來(lái)的動(dòng)機(jī)
理解java泛型最簡(jiǎn)單的方法是把它看成一種便捷語(yǔ)法,能節(jié)省你某些java類(lèi)型轉(zhuǎn)換(casting)上的操作:
1. listbox = ...;
2. apple apple = (0);
上面的代碼自身已表達(dá)的很清楚:box是一個(gè)裝有apple對(duì)象的list。get方法返回一個(gè)apple對(duì)象實(shí)例,這個(gè)過(guò)程不需要進(jìn)行類(lèi)型轉(zhuǎn)換。沒(méi)有泛型,上面的代碼需要寫(xiě)成這樣:
1. list box = ...;
2. apple apple = (apple) (0);
很明顯,泛型的主要好處就是讓編譯器保留參數(shù)的類(lèi)型信息,執(zhí)行類(lèi)型檢查,執(zhí)行類(lèi)型轉(zhuǎn)換操作:編譯器保證了這些類(lèi)型轉(zhuǎn)換的絕對(duì)無(wú)誤。
相對(duì)于依賴(lài)程序員來(lái)記住對(duì)象類(lèi)型、執(zhí)行類(lèi)型轉(zhuǎn)換——這會(huì)導(dǎo)致程序運(yùn)行時(shí)的失敗,很難調(diào)試和解決,而編譯器能夠幫助程序員在編譯時(shí)強(qiáng)制進(jìn)行大量的類(lèi)型檢查,發(fā)現(xiàn)其中的錯(cuò)誤。 泛型的構(gòu)成
由泛型的構(gòu)成引出了一個(gè)類(lèi)型變量的概念。根據(jù)java語(yǔ)言規(guī)范,類(lèi)型變量是一種沒(méi)有限制的標(biāo)志符,產(chǎn)生于以下幾種情況:
泛型類(lèi)聲明
泛型接口聲明
泛型方法聲明
泛型構(gòu)造器(constructor)聲明
泛型類(lèi)和接口
如果一個(gè)類(lèi)或接口上有一個(gè)或多個(gè)類(lèi)型變量,那它就是泛型。類(lèi)型變量由尖括號(hào)界定,放在類(lèi)或接口名的后面:
1. public interface listextends collection{
2.
3. ...
4. }
簡(jiǎn)單的說(shuō),類(lèi)型變量扮演的角色就如同一個(gè)參數(shù),它提供給編譯器用來(lái)類(lèi)型檢查的信息。 java類(lèi)庫(kù)里的很多類(lèi),例如整個(gè)collection框架都做了泛型化的修改。例如,我們?cè)谏厦娴牡谝欢未a里用到的list接口就是一個(gè)泛型類(lèi)。在那段代碼里,box是一個(gè)list對(duì)象,它是一個(gè)帶有一個(gè)apple類(lèi)型變量的list接口的類(lèi)實(shí)現(xiàn)的實(shí)例。編譯器使用這個(gè)類(lèi)型變量參數(shù)在get方法被調(diào)用、返回一個(gè)apple對(duì)象時(shí)自動(dòng)對(duì)其進(jìn)行類(lèi)型轉(zhuǎn)換。 實(shí)際上,這新出現(xiàn)的泛型標(biāo)記,或者說(shuō)這個(gè)list接口里的get方法是這樣的:
1. t get(int index);
get方法實(shí)際返回的是一個(gè)類(lèi)型為t的對(duì)象,t是在list聲明中的類(lèi)型變量。 泛型方法和構(gòu)造器(constructor)
非常的相似,如果方法和構(gòu)造器上聲明了一個(gè)或多個(gè)類(lèi)型變量,它們也可以泛型化。
1. public statict getfirst(listlist)
這個(gè)方法將會(huì)接受一個(gè)list類(lèi)型的參數(shù),返回一個(gè)t類(lèi)型的對(duì)象。
例子
你既可以使用java類(lèi)庫(kù)里提供的泛型類(lèi),也可以使用自己的泛型類(lèi)。
類(lèi)型安全的寫(xiě)入數(shù)據(jù)…
下面的這段代碼是個(gè)例子,我們創(chuàng)建了一個(gè)list實(shí)例,然后裝入一些數(shù)據(jù):
1. liststr = new arraylist();
2.
3. ("hello ");
4.
5. ("world.");
如果我們?cè)噲D在list裝入另外一種對(duì)象,編譯器就會(huì)提示錯(cuò)誤:
1. (1); //不能編譯
類(lèi)型安全的讀取數(shù)據(jù)…
當(dāng)我們?cè)谑褂胠ist對(duì)象時(shí),它總能保證我們得到的是一個(gè)string對(duì)象:
1. string mystring = (0);
遍歷
類(lèi)庫(kù)中的很多類(lèi),諸如iterator,功能都有所增強(qiáng),被泛型化。list接口里的 iterator()方法現(xiàn)在返回的是iterator,由它的t next()方法返回的對(duì)象不需要再進(jìn)行類(lèi)型轉(zhuǎn)換,你直接得到正確的類(lèi)型。
1. for (iteratoriter = or(); t();){
2.
3. string s = ();
4.
5. (s);
6.
7. }
使用foreach
“for each”語(yǔ)法同樣受益于泛型。前面的代碼可以寫(xiě)出這樣:
1. for (string s: str){
2.
3. (s);
4.
5. }
這樣既容易閱讀也容易維護(hù)。
自動(dòng)封裝(autoboxing)和自動(dòng)拆封(autounboxing)
在使用java泛型時(shí),autoboxing/autounboxing這兩個(gè)特征會(huì)被自動(dòng)的用到,就像下面的這段代碼:
1. listints = new arraylist();
2.
3. (0);
4.
5. (1);
6.
7.
8.
9.
sum = 0;
11.
(int i : ints){
13.
+= i;
15.
16.}
然而,你要明白的一點(diǎn)是,封裝和解封會(huì)帶來(lái)性能上的損失,所有,通用要謹(jǐn)慎的使用。 子類(lèi)型
在java中,跟其它具有面向?qū)ο箢?lèi)型的語(yǔ)言一樣,類(lèi)型的層級(jí)可以被設(shè)計(jì)成這樣:
在java中,類(lèi)型t的子類(lèi)型既可以是類(lèi)型t的一個(gè)擴(kuò)展,也可以是類(lèi)型t的一個(gè)直接或非直接實(shí)現(xiàn)(如果t是一個(gè)接口的話)。因?yàn)椤俺蔀槟愁?lèi)型的子類(lèi)型”是一個(gè)具有傳遞性質(zhì)的關(guān)系,如果類(lèi)型a是b的一個(gè)子類(lèi)型,b是c的子類(lèi)型,那么a也是c的子類(lèi)型。在上面的圖中: fujiapple(富士蘋(píng)果)是apple的子類(lèi)型
apple是fruit(水果)的子類(lèi)型
fujiapple(富士蘋(píng)果)是fruit(水果)的子類(lèi)型
所有java類(lèi)型都是object類(lèi)型的子類(lèi)型。
b類(lèi)型的任何一個(gè)子類(lèi)型a都可以被賦給一個(gè)類(lèi)型b的聲明:
1. apple a = ...;
2. fruit f = a;
泛型類(lèi)型的子類(lèi)型
如果一個(gè)apple對(duì)象的實(shí)例可以被賦給一個(gè)fruit對(duì)象的聲明,就像上面看到的,那么,list和 a list之間又是個(gè)什么關(guān)系呢?更通用些,如果類(lèi)型a是類(lèi)型b的子類(lèi)型,那c 和 c
答案會(huì)出乎你的意料:沒(méi)有任何關(guān)系。用更通俗的話,泛型類(lèi)型跟其是否子類(lèi)型沒(méi)有任何關(guān)系。