<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 19, 文章 - 1, 評(píng)論 - 21, 引用 - 0
    數(shù)據(jù)加載中……

    Java5新特性-泛型的使用總結(jié)(一)

    Java5的泛型的語(yǔ)法,已經(jīng)有很多帖子講了,這里依據(jù)我的一些個(gè)人理解做一次總結(jié),一方面是為了將我近一段時(shí)間對(duì)泛型的學(xué)習(xí)落實(shí)到紙面,畢竟有很多想 法,如果只是存在于腦子里,過(guò)一段時(shí)間也就淡忘了,總要留下點(diǎn)文字便于以后回顧;另一方面,也希望拿出點(diǎn)東西來(lái)與大家交流分享,這樣才能不斷的得到提高。

    泛型是什么
    簡(jiǎn)單的來(lái)說(shuō),泛型可以認(rèn)為是類型參數(shù)化的技術(shù)。相對(duì)于類型的參數(shù)化,在傳統(tǒng)的java代碼中,我們可以理解為所有的參數(shù)都是值的參數(shù)化,例如以下代碼:
     1 package org.dbstar.generic;
     2 
     3 public class ValueHolder {
     4     private String value;
     5 
     6     public ValueHolder(String value) {
     7         this.value = value;
     8     }
     9 
    10     public String getValue() {
    11         return value;
    12     }
    13 
    14     public void setValue(String value) {
    15         this.value = value;
    16     }
    17 }
    其中的成員變量、構(gòu)造函數(shù)參數(shù)和方法參數(shù),都可以認(rèn)為是值的參數(shù)化的體現(xiàn)。但是,不管值如何變化,值的類型只能局限于String及其子類,如果我們想讓 ValueHolder同時(shí)也能持有一個(gè)Integer類型的值,那么在傳統(tǒng)的Java代碼中,只能將成員變量的類型定義為Object,如下:
     1 package org.dbstar.generic;
     2 
     3 public class ValueHolder {
     4     private Object value;
     5 
     6     public ValueHolder(Object value) {
     7         this.value = value;
     8     }
     9 
    10     public Object getValue() {
    11         return value;
    12     }
    13 
    14     public void setValue(Object value) {
    15         this.value = value;
    16     }
    17 }
    使用Object版的ValueHolder的代碼看起來(lái)會(huì)像這樣:
    1     public static void main(String[] args) {
    2         ValueHolder vhi = new ValueHolder(new Integer(1));
    3         ValueHolder vhs = new ValueHolder("abc");
    4         ValueHolder vho = new ValueHolder(new Object());
    5         System.out.println("ValueHolder of Integer=" + vhi.getValue());
    6         System.out.println("ValueHolder of String=" + vhs.getValue());
    7         System.out.println("ValueHolder of Object=" + vho.getValue());
    8     }
    輸出結(jié)果為:
    1 ValueHolder of Integer=1
    2 ValueHolder of String=abc
    3 ValueHolder of Object=java.lang.Object@757aef
    幸運(yùn)的是,Java5給我們提供了一個(gè)將value的類型也作為一個(gè)參數(shù)來(lái)設(shè)置的方法,那就是泛型,下面是將value的類型也參數(shù)化后的 ValueHolder實(shí)現(xiàn):
     1 package org.dbstar.generic;
     2 
     3 public class ValueHolder<E> {
     4     private E value;
     5 
     6     public ValueHolder(E value) {
     7         this.value = value;
     8     }
     9 
    10     public E getValue() {
    11         return value;
    12     }
    13 
    14     public void setValue(E value) {
    15         this.value = value;
    16     }
    17 }
    其中,value就是值的參數(shù)化,value的類型現(xiàn)在定義為E,<E>就是類型的參數(shù)化。使用ValueHolder的代碼也相應(yīng)發(fā)生了變 化:
    1         ValueHolder<Integer> vhi = new ValueHolder<Integer>(new Integer(1));
    2         ValueHolder<String> vhs = new ValueHolder<String>("abc");
    3         ValueHolder<Object> vho = new ValueHolder<Object>(new Object());
    4         System.out.println("ValueHolder of Integer=" + vhi.getValue().intValue());
    5         System.out.println("ValueHolder of String=" + vhs.getValue().substring(1));
    6         System.out.println("ValueHolder of Object=" + vho.getValue());
    根據(jù)ValueHolder類型定義的不同,類型參數(shù)<E>在不同場(chǎng)合代表了不同的實(shí)際類型。

    泛型的賦值
    與值參數(shù)的賦值不同的是,類型參數(shù)的賦值有其特殊性,下面來(lái)逐一說(shuō)明:
    A。同類型賦值:
    1         ValueHolder<Integer> vhi = new ValueHolder<Integer>(new Integer(1));
    2         ValueHolder<Integer> vhi2 = vhi;
    3         vhi2.setValue(new Integer(2));
    4         System.out.println("ValueHolder of Integer2=" + vhi2.getValue().intValue());
    這種賦值后的變量,與源變量具有完全一致的操作,包括獲取泛型變量和在方法參數(shù)中設(shè)置泛型變量。
    B。超類型賦值:
    1         ValueHolder<Integer> vhi = new ValueHolder<Integer>(new Integer(1));
    2         ValueHolder<Number> vhi3 = vhi;//實(shí)際上,這是不允許的,會(huì)導(dǎo)致編譯錯(cuò)誤
    3         ValueHolder<? extends Number> vhi2 = vhi;//必須要這樣寫
    4         System.out.println("ValueHolder of Integer2=" + vhi2.getValue().intValue());
    5         vhi2.setValue(new Integer(2));//超類型賦值后,操作受到限制,會(huì)導(dǎo)致編譯錯(cuò)誤
    6         vhi2.setValue(null);//只有設(shè)置null值才是合法的,其他值一概不允許設(shè)置
    這種賦值后的變量,能調(diào)用返回值為泛型變量的方法,但是只能使用新泛型變量類型的方法,而不能再使用原有泛型變量類型上的方法,這樣說(shuō)有點(diǎn)繞,舉例來(lái)說(shuō), 上面的vhi2就只能使用Number類型上定義的方法,而無(wú)法再使用原先在Integer類型上定義的方法了。
    可賦值的超類型可以是原類型的任何超類型或者接口,這些賦值都是類型安全的,不會(huì)引發(fā)任何編譯時(shí)警告。例如:
    1         ValueHolder<? extends Number> vhn = vhi;//超類
    2         ValueHolder<? extends Object> vho2 = vhi;//超類
    3         ValueHolder<? extends Comparable> vhc = vhi;//接口
    賦值后的帶?的泛型,還能繼續(xù)賦值給超類,例如:
    1         ValueHolder<? extends Number> vhn = vhi;
    2         ValueHolder<? extends Object> vho3 = vhn;
    ValueHolder<?>等效于ValueHolder<? extends Object>,因?yàn)镺bject是所有類的超類。
    C。子類型賦值:
    1         ValueHolder<? extends Number> vhi2 = vhi;//必須要這樣寫
    2
             @SuppressWarnings("unchecked")
    3         ValueHolder<Integer> vhi3 = (ValueHolder<Integer>) vhi2;
    和值參數(shù)的賦值一樣,超類型的泛型變量往子類型的泛型變量賦值,需要強(qiáng)制轉(zhuǎn)換,轉(zhuǎn)換后的vhi3與vhi具有完全一致的操作。但是,需要注意的一點(diǎn)是,這 種轉(zhuǎn)換會(huì)導(dǎo)致一個(gè)unchecked的編譯時(shí)警告,而且,若無(wú)法完成轉(zhuǎn)換,會(huì)導(dǎo)致一個(gè)運(yùn)行時(shí)的ClassCastException異常,例如:
    1         @SuppressWarnings("unchecked")
    2         ValueHolder<Double> vhi3 = (ValueHolder<Double>) vhi2;//這里不會(huì)拋出異常
    3         vhi3.setValue(new Double(12.5));
    4         System.out.println("ValueHolder of Double=" + vhi3.getValue().doubleValue());
    5         System.out.println("ValueHolder of Integer=" + vhi.getValue().intValue());//會(huì)在這里拋出ClassCastException
    上例中,vhi2將Integer類型轉(zhuǎn)換成了超類型Number,而vhi3又將Number強(qiáng)類型轉(zhuǎn)換成了Double,這也是允許的,不會(huì)引發(fā)編譯 時(shí)錯(cuò)誤或者運(yùn)行時(shí)錯(cuò)誤。下面甚至還可以給vhi3設(shè)置一個(gè)Double的值,值得注意的是,vhi3其實(shí)就是vhi,我們給一個(gè)Integer的變量設(shè)置 了一個(gè)Double的值,卻沒有引發(fā)任何異常,還真是詭異的很。隨后,我們?cè)谡{(diào)用vhi.getValue().intValue()時(shí),才終于引發(fā)了 ClassCastException。由此可見,這種強(qiáng)類型轉(zhuǎn)換有時(shí)候會(huì)使錯(cuò)誤變得非常隱晦難于發(fā)現(xiàn),我們應(yīng)該盡量避免這種轉(zhuǎn)換的使用。
    D。賦值給傳統(tǒng)代碼(row type賦值):
    1         @SuppressWarnings("unchecked")
    2         ValueHolder vh = vhi;
    3         vh.setValue(new Integer(3));
    不指定類型參數(shù)的泛型類,稱之為row type,這是Java5泛型為了與老版本的代碼兼容而選擇的一種處理方式。Row type的泛型類中,所有的類型參數(shù)都被當(dāng)做Object來(lái)處理,也就是說(shuō),ValueHolder可以當(dāng)做 ValueHolder<Object>來(lái)處理,但是與ValueHolder<Object>又有所不同,因?yàn)? ValueHolder<Integer>是不能被轉(zhuǎn)換為ValueHolder<Object>的,而能轉(zhuǎn)換的ValueHolder<? extends Object>又不能調(diào)用setValue方法(當(dāng)然可以設(shè)置null值,而其他非null值不能設(shè)置)。值得注意的是,轉(zhuǎn)換到傳統(tǒng)代碼,以及使用 傳統(tǒng)代碼調(diào)用有泛型參數(shù)的方法,會(huì)引起一個(gè)unchecked的編譯時(shí)警告。
    E。傳統(tǒng)代碼(row type)賦值給泛型
    與第三點(diǎn):子類型賦值類似,可以將傳統(tǒng)代碼看做是ValueHolder<? extends Object>,同樣需要強(qiáng)類型轉(zhuǎn)換,以及存在類型安全問題。

    posted on 2010-02-05 00:25 dbstar 閱讀(617) 評(píng)論(1)  編輯  收藏 所屬分類: Java

    評(píng)論

    # re: Java5新特性-泛型的使用總結(jié)(一)[未登錄]  回復(fù)  更多評(píng)論   

    學(xué)習(xí)一下經(jīng)理對(duì)泛型的理解。。。。。。古老的2010~~~
    2013-01-23 16:02 | zhou

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 91视频免费观看高清观看完整| 亚洲视频在线精品| 国产午夜免费高清久久影院| 亚洲av永久无码精品网址| 亚洲视频在线观看| 激情综合色五月丁香六月亚洲| 国产精品国产自线拍免费软件| 四虎最新永久免费视频| 成人性生交大片免费看好| 亚洲一区二区三区免费| 日日摸日日碰夜夜爽亚洲| 亚洲精品中文字幕无乱码麻豆| 久久青草亚洲AV无码麻豆| 国产亚洲精品影视在线产品| 亚洲AV无码之日韩精品| 在线免费一区二区| 亚洲成在人线aⅴ免费毛片| 69国产精品视频免费| 三年片在线观看免费大全电影 | 久久九九全国免费| 三级片免费观看久久| 99亚洲乱人伦aⅴ精品| 亚洲精品福利你懂| 亚洲影视自拍揄拍愉拍| 亚洲国产美女精品久久久久| 中文字幕亚洲色图| 久久久亚洲裙底偷窥综合| 久久精品a亚洲国产v高清不卡| 久久久无码精品亚洲日韩按摩| 亚洲激情中文字幕| 久久久久亚洲AV无码专区体验| 91亚洲va在线天线va天堂va国产| 亚洲国产精品婷婷久久| 亚洲av丰满熟妇在线播放| 亚洲国产精品lv| 亚洲国产精品专区| 7777久久亚洲中文字幕| 亚洲精品无码成人片久久不卡| 亚洲精品日韩一区二区小说| 亚洲AV成人一区二区三区观看| 国产亚洲人成在线影院|