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

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

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

    隨筆 - 19, 文章 - 1, 評論 - 21, 引用 - 0
    數據加載中……

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

    Java5的泛型的語法,已經有很多帖子講了,這里依據我的一些個人理解做一次總結,一方面是為了將我近一段時間對泛型的學習落實到紙面,畢竟有很多想法,如果只是存在于腦子里,過一段時間也就淡忘了,總要留下點文字便于以后回顧;另一方面,也希望拿出點東西來與大家交流分享,這樣才能不斷的得到提高。

    泛型是什么
    簡單的來說,泛型可以認為是類型參數化的技術。相對于類型的參數化,在傳統的java代碼中,我們可以理解為所有的參數都是值的參數化,例如以下代碼:
     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 }
    其中的成員變量、構造函數參數和方法參數,都可以認為是值的參數化的體現。但是,不管值如何變化,值的類型只能局限于String及其子類,如果我們想讓ValueHolder同時也能持有一個Integer類型的值,那么在傳統的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的代碼看起來會像這樣:
    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     }
    輸出結果為:
    1 ValueHolder of Integer=1
    2 ValueHolder of String=abc
    3 ValueHolder of Object=java.lang.Object@757aef
    幸運的是,Java5給我們提供了一個將value的類型也作為一個參數來設置的方法,那就是泛型,下面是將value的類型也參數化后的ValueHolder實現:
     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就是值的參數化,value的類型現在定義為E,<E>就是類型的參數化。使用ValueHolder的代碼也相應發生了變化:
    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());
    根據ValueHolder類型定義的不同,類型參數<E>在不同場合代表了不同的實際類型。

    泛型的賦值
    與值參數的賦值不同的是,類型參數的賦值有其特殊性,下面來逐一說明:
    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());
    這種賦值后的變量,與源變量具有完全一致的操作,包括獲取泛型變量和在方法參數中設置泛型變量。
    B。超類型賦值:
    1         ValueHolder<Integer> vhi = new ValueHolder<Integer>(new Integer(1));
    2         ValueHolder<Number> vhi3 = vhi;//實際上,這是不允許的,會導致編譯錯誤
    3         ValueHolder<? extends Number> vhi2 = vhi;//必須要這樣寫
    4         System.out.println("ValueHolder of Integer2=" + vhi2.getValue().intValue());
    5         vhi2.setValue(new Integer(2));//超類型賦值后,操作受到限制,會導致編譯錯誤
    6         vhi2.setValue(null);//只有設置null值才是合法的,其他值一概不允許設置
    這種賦值后的變量,能調用返回值為泛型變量的方法,但是只能使用新泛型變量類型的方法,而不能再使用原有泛型變量類型上的方法,這樣說有點繞,舉例來說,上面的vhi2就只能使用Number類型上定義的方法,而無法再使用原先在Integer類型上定義的方法了。
    ValueHolder<?>等效于ValueHolder<? extends Object>,因為Object是所有類的超類。
    C。子類型賦值:
    1         @SuppressWarnings("unchecked")
    2         ValueHolder<Integer> vhi3 = (ValueHolder<Integer>) vhi2;
    和值參數的賦值一樣,超類型的泛型變量往子類型的泛型變量賦值,需要強制轉換,轉換后的vhi3與vhi具有完全一致的操作。但是,需要注意的一點是,這種轉換會導致一個unchecked的編譯時警告,而且,若無法完成轉換,會導致一個運行時的ClassCastException異常,例如:
    1         @SuppressWarnings("unchecked")
    2         ValueHolder<Double> vhi3 = (ValueHolder<Double>) vhi2;//這里不會拋出異常
    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());//會在這里拋出ClassCastException
    上例中,vhi2將Integer類型轉換成了超類型Number,而vhi3又將Number強類型轉換成了Double,這也是允許的,不會引發編譯時錯誤或者運行時錯誤。下面甚至還可以給vhi3設置一個Double的值,值得注意的是,vhi3其實就是vhi,我們給一個Integer的變量設置了一個Double的值,卻沒有引發任何異常,還真是詭異的很。隨后,我們在調用vhi.getValue().intValue()時,才終于引發了ClassCastException。由此可見,這種強類型轉換有時候會使錯誤變得非常隱晦難于發現,我們應該盡量避免這種轉換的使用。
    D。傳統代碼賦值:
    1         @SuppressWarnings("unchecked")
    2         ValueHolder vh = vhi;
    3         vh.setValue(new Integer(3));
    不指定類型參數的泛型類,稱之為row type,這是Java5泛型為了與老版本的代碼兼容而選擇的一種處理方式。Row type的泛型類中,所有的類型參數都被當做Object來處理,也就是說,ValueHolder可以當做ValueHolder<Object>來處理,但是與ValueHolder<Object>又有所不同,因為ValueHolder<Integer>是不能被轉換為ValueHolder<Object>的,而能轉換的ValueHolder<? extends Object>又不能調用setValue方法(當然可以設置null值,而其他非null值不能設置)。值得注意的是,轉換到傳統代碼,以及使用傳統代碼調用有泛型參數的方法,會引起一個unchecked的編譯時警告。

    posted on 2010-02-04 23:55 dbstar 閱讀(389) 評論(0)  編輯  收藏 所屬分類: Java


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲乱码日产精品BD在线观看| 国产青草亚洲香蕉精品久久| 成人啪精品视频免费网站| 精品国产日韩亚洲一区91| 国产成人亚洲综合无码精品| 日韩午夜理论免费TV影院| 国产精品亚洲专区无码牛牛| 亚洲AV无码专区国产乱码4SE| 免费中文熟妇在线影片| 一个人看www免费高清字幕| 亚洲午夜精品在线| 国产成人综合亚洲亚洲国产第一页 | **真实毛片免费观看| 国产亚洲欧美在线观看| 亚洲国产精品久久久久久| 白白国产永久免费视频| 亚洲午夜免费视频| 免费一级做a爰片久久毛片潮| 亚洲码一区二区三区| 亚洲午夜福利精品久久| 24小时免费直播在线观看| 日本一区午夜艳熟免费| 国产精品亚洲专区无码牛牛| 亚洲精品视频久久| 国产成人A亚洲精V品无码| 免费看大美女大黄大色| 中文字幕在线观看免费视频 | 国内外成人免费视频| 性xxxxx大片免费视频| 日产久久强奸免费的看| 亚洲人成网站在线在线观看| 亚洲av中文无码乱人伦在线咪咕 | 成人免费无码视频在线网站| 两个人看的www免费| 免费人成又黄又爽的视频在线电影| 亚洲性无码av在线| 亚洲AV无码国产精品色午友在线 | 国产亚洲欧美日韩亚洲中文色| 亚洲人成影院午夜网站| 亚洲天天在线日亚洲洲精| 人人鲁免费播放视频人人香蕉|