日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDK5.0新特性之:泛型

發(fā)布時間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDK5.0新特性之:泛型 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文/陳剛 2005-11-09?

一、前言

  泛型這個詞在現(xiàn)在的JAVA挺時髦,光從字面上你是無法知道它代表些什么東東的,所以我們還是不要從字面去理解,而是從一些實例去了解它吧。

二、泛型之前的日子

  JDK1.4之前是沒有泛型的概念的,所以我們才會有下面的代碼:

List list = new ArrayList();
list.add("aaaa");
list.add("bbbb");
list.add("cccc"); for (Iterator it = list.iterator(); it.hasNext();) {
String str = (String) it.next();
System.out.println(str);
}

  上面是一段很平常的代碼,在一個List集合加入一些字符串,然后再用一個遍歷循環(huán)把它打印出來。“String str = (String) it.next()”這一句我們可以看到List取出值都是Object,所以我們要得String型,還要做一個類型轉(zhuǎn)換,真是麻煩。更麻煩的是list.add(Object obj)的參數(shù)是Object類型,所以如果我們一不小心把list.add("cccc");寫成list.add(new Integer(76));程序在循環(huán)打印的類型轉(zhuǎn)換中就會出錯。

  問題:我們能不能讓add方法只認String型呢?
回答:可以!用JDK5.0的泛型。

三、泛型后的幸福生活

  JAVA有了泛型后,就象十年的老光棍討了老婆,那個好處自不待言。我們來看看上面的例子改成泛型的寫法是怎么樣的:

List<String> list = new ArrayList<String>();
list.add("aaaa");
list.add("bbbb");
list.add("cccc"); for (Iterator<String> it = list.iterator(); it.hasNext();) {
String str=it.next();
System.out.println(str);
}

  看到差別了嗎?泛型其實很簡單,就是在定義類型的后面加上"<類型>"這樣子的聲明就行了,它主要還有以下差別:

  • list.add方法只能接受String類型。list.add(new Integer(76))這樣的語句不需要運行程序,在編譯時就會檢查通不過。
  • it.next()的返回值不再是Object,而變成了String

  當然我們其實在循環(huán)部份也可以象下面這么寫,是不是簡潔了很多呢 :-)

List<String> list = new ArrayList<String>();
list.add("aaaa");
list.add("bbbb");
list.add("cccc"); for (String str : list) {
System.out.println(str);
}

  當然需要說明的是,List不僅可以List<String>,也可以是List<Integer>等等其他任何類型。

四、更深入了解泛型

(1)層層推進的泛型聲明

  “List<List> list;”表示什么呢?就是只接收List型的參數(shù),比如:

??????? List<List> list = new ArrayList<List>();
list.add(new ArrayList());
list.add(new Vector());
list.add(new LinkedList());

  這里要注意List是接口,ArrayList、Vector、LinkedList都是這一接口下的實現(xiàn)類。下面這個有點怪異了,“List<List<String>> list;”表示它只接受List型的參數(shù),而且這種List型的參數(shù)又是只是只接受String型,有點層層推進的味道在里面了。

??????? List<List<String>> list = new ArrayList<List<String>>();
list.add(new ArrayList<String>());
list.add(new Vector<String>());
list.add(new LinkedList<String>());

(2)使用泛型上限通通配符:extends

  這里要著重強調(diào)一點:變量的泛型聲明和方法的參數(shù)的泛型聲明有很大差別。

  變量聲明成某類型,同時也可以接受它的子類。比如說Integer、Long、Float都是抽象類Number的子類,所以下面的代碼一點問題也沒有:

??????? List<Number> list = new ArrayList<Number>();
list.add(new Integer(1));
list.add(new Long(1));
list.add(new Float(1.2));

  但如果換成方法參數(shù)的泛型聲明則要嚴格得多了:子類也是不行的。比如下面的代碼就是錯誤的,因為printList參數(shù)只接受Number值的List,就是是Number子類的Integer值的List也不行。

??? public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(new Integer(1));
list.add(new Integer(2));
printList(list);
}

private static void printList(List<Number> list){
for (Number num : list) {
System.out.println(num);
}
}

 上面代碼修改的方法有兩個,如下

修改方法一:改變量的泛型聲明
將 List<Integer> list = new ArrayList<Integer>();
改為 List<Number> list = new ArrayList<Number>();

修改方法二:用界限通配符改方法參數(shù)的泛型聲明
將 printList(List<Number> list)
改為 printList(List<? extends Number> list)
說明:extends 的含義就是表示參數(shù)可以接受Number型的子類。

(3)使用泛型下限通通配符:super

??  在上限就有下限,下限行就是super,用法和extends一樣,含義則和extends相反。比如printList(List<? super Integer> list)表示參數(shù)可以接受Integer型及Integer型的超類,即Number了,當然也包括Object這個頂級類。

(4)配置符:?

  ?表示可以接受任何類型,不過我覺得它用得不多,因為printList(List<?> list)和printList(List list)的作用是一樣的。

五、創(chuàng)建一個支持泛型的類

(1)創(chuàng)建一個泛型的類

public class Point<T> {
T x;
T y; ??? public T getX() {
return x;
} ??? public T getY() {
return y;
} ??? public void setX(T x) {
this.x = x;
} ??? public void setY(T y) {
this.y = y;
}
}

  使用這個類的代碼如下:

??????? Point<Integer> p = new Point<Integer>();
p.setX(new Integer(1));
p.setY(new Integer(2));

Point<String> b = new Point<String>();
b.setX("1");
b.setY("2");

  說明:在Point<T>的定義中,T并非關(guān)鍵字,你也可以這樣定義Point<ABC>,當然一般還是寫T吧,簡單也規(guī)范。

(2)泛型類的繼承與實現(xiàn)

  java.util.Comparator類是JDK里用來排序的,其源代碼如下:

package java.util;
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}

?? 一個實現(xiàn)此接口的類如下:

??? public class MyComparator<T> implements Comparator<ObjectInstance> {
public int compare(ObjectInstance o1, ObjectInstance o2) {
String s1 = o1.getObjectName().getCanonicalName();
String s2 = o2.getObjectName().getCanonicalName();
return s1.compareToIgnoreCase(s2);
}
}

  說明:ObjectInstance可能大家還太明白,這是我實際項目中的一段代碼(關(guān)于JMX的),ObjectInstance全稱javax.management.ObjectInstance。MyComparator的使用代碼如下:

Set set = ......(省略)
List<ObjectInstance> mbeans = new ArrayList<ObjectInstance>(set);
Collections.sort(mbeans, new MyComparator<ObjectInstance>());

六、最后的感言

  JAVA有了泛型就象老光棍討了老婆,好處大大的,但和女人一樣麻煩也跟著來了:它的嚴格類型檢查,使隱藏的BUG更少。有些地方確實也使代碼簡潔了,有些地方卻會使得代碼更復(fù)雜。所以運用之妙在于是否用得適當,盡量把泛型往簡單里用,別越搞越復(fù)雜了。?

參考資料

J2SE 5.0中的泛型 http://www.matrix.org.cn/resource/article/43/43634_java_generics.html

作者簡介

陳剛,廣西桂林人,著作有《Eclipse從入門到精通》
您可以通過其博客了解更多信息和文章:http://www.ChenGang.com.cn

總結(jié)

以上是生活随笔為你收集整理的JDK5.0新特性之:泛型的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。