欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
J2SE5.0 實(shí)例---泛型_IT中國 ITcnw.Com
J2SE5.0 實(shí)例---泛型
作者:佚名 文章來(lái)源:不詳 點(diǎn)擊數: 105866 更新時(shí)間:2005-11-30
泛型
簡(jiǎn)介
 
泛型其實(shí)并不是一種新的語(yǔ)言元素,C++中早就就有,但是在C++之后的java卻沒(méi)有吸收這個(gè)特性,現在Java也有了泛型的特性,大概也和.Net的競爭有關(guān)系吧。
首先看泛型的一個(gè)應用。
在過(guò)去,我們可能經(jīng)常要寫(xiě)一些類(lèi)似這樣的代碼:
List stringList=new LinkedList();
stringList.add("firstString");
stringList.add("secondString");
String str=(String)stringList.iterator().next();
 
 
實(shí)際上第三行對String的類(lèi)型轉換意義并不大,因為通常我們如果在操作一個(gè)List,都是知道這個(gè)List里面放的是什么類(lèi)型對象的,但是我們如果不這樣寫(xiě)又通不過(guò)語(yǔ)法檢查。
利用java的泛型機制,我們可以這么寫(xiě):
List<String> stringList=new LinkedList<String>();
stringList.add("firstString");
stringList.add("secondString");
String str=stringList.iterator().next();
這樣做的好處是在定義容器的時(shí)候就指明了容器中的類(lèi)型,一方面我們不再需要取一個(gè)元素時(shí)候做強制類(lèi)型轉換,另外一方面如果在這個(gè)容器中放入的對象類(lèi)型不符合要求,那么會(huì )在編譯時(shí)候產(chǎn)生一個(gè)錯誤,而不是在運行時(shí)候才拋出一個(gè)異常。
另外這樣也提高了程序的可讀性。
泛型類(lèi)型的定義
下面是一個(gè)簡(jiǎn)單的使用泛型類(lèi)的定義:
public class MyGenericClass<T> {
private T value;
 
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
值得注意的一點(diǎn)是,靜態(tài)變量不能夠使用泛型定義,也就是說(shuō)類(lèi)似下面的語(yǔ)句是非法的:
 
 
public class MyGenericClass<T> {
public static T value;//錯誤的定義
}
此外,泛型的定義不會(huì )被繼承,舉個(gè)例子來(lái)說(shuō),如果A是B的子類(lèi),而C是一個(gè)聲明了泛型定義的類(lèi)型的話(huà),C<A>不是C<B>的子類(lèi)。為了更好的說(shuō)明,可以看下面的代碼,這段代碼是錯誤的。
List<String> strList =new ArrayList<String>();
List<Object> objList=strList;  //錯誤的賦值
 
 
不過(guò)這樣一段代碼是正確的:
List<Object> strList =new ArrayList<Object>();
strList.add("jsdkfjsdl");
統配類(lèi)型
假設我們需要這樣一個(gè)函數,使用它可以把一個(gè)集合中所有的元素打印出來(lái),在以前我們可能這樣定義:
void printCollection(Collection c) {
Iterator i = c.iterator();
for (k = 0; k < c.size(); k++)
{
System.out.println(i.next());
}
}
使用新的泛型特性我們可能會(huì )這樣寫(xiě):
void printCollection(Collection<Object> c)
{
for (Object e : c)
{
System.out.println(e);
}
}
但是這樣有一個(gè)問(wèn)題,假如我們現在有個(gè)對象類(lèi)型是Collection<String>,那么我們不能夠將它作為參數傳給printCollection,因為Collection<String>并不是Collection<Object>的子類(lèi)。
為了解決這個(gè)問(wèn)題,我們可以使用統配類(lèi)型?,也就是定義成下面這個(gè)樣子:
void printCollection(Collection<?> c)
{
for (Object e : c)
{
System.out.println(e);
}
}
可以說(shuō)Collection<?>是所有Collection的父類(lèi)。
再來(lái)看一段下面的代碼
private void clearAllMaps(Collection<Map> c)
{
for(Map m:c)
{
m.clear();
}
}
毫無(wú)疑問(wèn),它也存在上面我們所說(shuō)的問(wèn)題,也就是對HashMap之類(lèi)Map的子類(lèi)無(wú)法進(jìn)行操作,但是如果我們將參數改成Collection<?>又不大合理,因為我們只希望對父類(lèi)為Map的子類(lèi)進(jìn)行操作,那么我們可以這樣改寫(xiě):
private void clearAllMaps(Collection<? extends Map> c)
{
for(Map m:c)
{
m.clear();
}
}
類(lèi)似于? extends Map之類(lèi)的統配符稱(chēng)為限定統配類(lèi)型。
假設一個(gè)對象h類(lèi)型為Collection<HashMap>,那么我們將h作為參數傳給clearAllMaps,如下面一段代碼所示:
List<HashMap<String,String>> h=new ArrayList<HashMap<String,String>>();
HashMap<String,String> m=new HashMap<String,String>();
m.put("key","value");
h.add(m);
clearAllMaps(h);
對于在類(lèi)似于上面所說(shuō),使用了? extend XXX的方法,值得注意的一點(diǎn)是不能夠在方法體內用XXX的子類(lèi)對象作為代替。如下面一段代碼是錯誤的:
public void addRectangle(List<? extends Shape> shapes)
{
shapes.add(0, new Rectangle()); // 錯誤用法!
}
這里我們假設Rectangle是Shape的一個(gè)子類(lèi)。
不允許這樣寫(xiě)的原因比較簡(jiǎn)單,因為調用該方法時(shí)候參數類(lèi)型可能是Shape的另外一個(gè)子類(lèi)。假如說(shuō)Shape除了Rectangle這個(gè)子類(lèi)以外還有另外一個(gè)子類(lèi)Circle,那么我們可以把一個(gè)List<Circle>類(lèi)型的對象作為參數傳給這個(gè)方法(注意這樣是合法的),而在方法體內卻把一個(gè)Rectangle對象放到了shapes里面,這顯然是不合理的。
除了extends,在泛型參數類(lèi)型中還可以使用super關(guān)鍵字,參照下面一段程序:
private void addString(Collection <? super String> c)
{
c.add("a String");
}
 
 
泛型函數
我們在前面提到了統配類(lèi)型,現在讓我們來(lái)設想一個(gè)函數,它實(shí)現這樣的功能,將一個(gè)數組中的元素添加到一個(gè)Collection中,為了保證程序的通用性,我們可能會(huì )寫(xiě)出另外一段錯誤的代碼:
private void fromArrayToCollection(Object[] a, Collection<?> c)
{
for (Object o : a)
{
c.add(o); // 錯誤的代碼
}
}
那么這個(gè)函數應該怎么寫(xiě)呢?我們可以通過(guò)對函數添加泛型參數的方法實(shí)現,如下面所示:
private <T> void  exfromArrayToCollection(T[] a,  Collection<T> c)
{
for (T o : a)
{
c.add(o); //這樣是正確的
}
}
 
那么,在什么時(shí)候我們應該使用統配類(lèi)型,什么時(shí)候我們應該使用泛型函數呢?答案是取決于函數參數之間,函數參數和返回值之間的類(lèi)型依賴(lài)性。
如果一個(gè)函數的參數類(lèi)型與函數返回的參數沒(méi)有必然關(guān)聯(lián),同時(shí)對于該函數其他的參數的類(lèi)型也沒(méi)有依賴(lài)關(guān)系,那么我們就應該使用統配符,否則就應該使用泛型函數。
為了更清楚地說(shuō)明這一點(diǎn),我們可以看一下java.util包中Collections類(lèi)型幾個(gè)方法的定義:
class Collections {
static void swap(List<?> list, int i, int j) {...}
static <T> void  copy                                 (List<? super T> dest, List<? extends T> src)    {...}
}
其中swap函數實(shí)際上也可以這樣定義:
static <T>void swap(List<T> list, int i, int j) {...}
但是注意到這里泛型類(lèi)型參數T只在參數中用到了一次,也就是說(shuō)它和函數其他部分沒(méi)有依賴(lài)性,這可以看作是我們應該使用?的一個(gè)標志。
copy方法中,拷貝源src中的元素必須是dest所能夠接受的,src中的元素必須是T的一個(gè)子類(lèi),但是具體它是哪種子類(lèi)我們又不必關(guān)心,所以方法中使用了泛型作為一個(gè)類(lèi)型參數,同時(shí)也用了統配類(lèi)型作為第二類(lèi)型參數
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
淺談Java泛型編程
方法的重載和重寫(xiě)
.NET高級編程之泛型詳解
C#基礎到入門(mén)(一篇就夠了)
Java基礎
J2SE 5.0中的泛型
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久