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

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

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

    求索

    Make it work, make it right, make it fast and make it open。
    posts - 8, comments - 11, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    關于Generics的一點兒理解

    Posted on 2005-07-06 15:57 Java求索 閱讀(922) 評論(5)  編輯  收藏 所屬分類: Java

    JDK5.0已經release很久了,但一直沒機會好好學習一下,今天可有機會了。

    先來看一段代碼:

    public class TestDate {

        
    public static void main(String[] args) {
            Date date 
    = new Date();
            Object 
    object = new Object();
            Timestamp stamp 
    = new Timestamp(date.getTime());
            System.
    out.println("date&stamp:" + date.compareTo(stamp));
            System.
    out.println("stamp&date:" + stamp.compareTo(date));
            System.
    out.println("date&object:" + date.compareTo(object));
        }
    }


    這段代碼看上去很普通,但是如果用1.4和1.5分別編譯就會出現不同的結果。先來說用1.4編譯的情況:首先用1.4編譯,編譯器不會報錯,如果運行的話,前面兩個輸出語句會分別打印“0,0”,而第三個會throw一個ClassCast exception. 因為Date不能與object比較,但是為什么能編譯通過呢?察看JDK源代碼就可以知道了,Date實現了Comparable接口,這個接口中的CompareTo()方法的參數就是Object。所以Date也不得不有一個以Object為參數的CompareTo()方法,但是這個方法是沒有意義的,Date應該與Date比較,所以Date這個Class里面就出現了兩個ComparaTo方法,一個是以Date為參數,另一個是以Object為參數,這是1.4以前,不得不采用的方法。不然Date就沒法實現Comparable接口了。

    JDK1.5中Generics的出現解決了這個問題,如果看1.5中Date類的源代碼的話,就會發現它只有一個CompareTo()方法了,那它怎么來實現Comparable接口呢,這就是Generics的功勞了。在Date聲明時,實現Comparable接口是這么寫的:...Comparable...,并且Comparable接口的聲明是這樣的:Comparable。這個T代表Type。它可以是任何Object。Comparable的實現類只要說明T是什么具體類型就可以了。因此,Date就可以只有一個CompareTo()方法,又可以實現Comparable接口了。如果用1.5編譯上面的Code的話,就會發現這段Code是不能編譯通過的,編譯器會提示“Severity Description Resource In Folder Location Creation Time 2 The method compareTo(Date) in the type Date is not applicable for the arguments (Object)”,這就避免了1.4中出現的問題。我想如果使用了1.5以后咱們編寫代碼時,出現ClassCastException的幾率就會很小了,因為編譯器會替你發現這樣的錯誤。

    這就是Generics的好處了。

    但是還有一點值得考慮,如果我們去掉錯誤的那一行代碼,在1.5中編譯然后運行,會發現還有地方與1.4的不同。第一行輸出語句會打印1,而不是0,這說明1.5認為具有相同時間的timestamp和date是不同的,但1.4認為它們相同。我有看了一下1.5和1.4的源代碼,發現它們CompareTo(Date ...)的實現方法是不一樣的,可能問題就出現在這里。我沒有試著去讀它的代碼,等有時間,一定好好研究一下。

    最后,還有一個問題,如果用1.5編譯并運行,會throw一個ClassCastException,而用1.4則不會出現這個問題。我想這是因為timestamp繼承了Date的CompareTo()方法,所以一個timestamp就可以與Date比較了,但是應用了Generics以后這種情況是不允許的,而且代碼也沒有特殊處理,因此就會有Exception了。看來Generics也會帶來一些其他的問題。

    我想這種情況是可以避免的,原則就是只比較具有相同類型的兩個對象,而不與其父類或子類比較。如果必須比較的話,也應該用相應的方法轉化為相同的類,再進行比較。


    評論

    # re: 關于Generics的一點兒理解  回復  更多評論   

    2005-07-06 18:27 by emu
    這是jdk1.5一個已經報告的bug:
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5103041


    問題在于在jdk1.5中Timestamp多定義了一個比較方法:

    public int compareTo(java.util.Date o) {
    return compareTo((Timestamp)o);
    }

    這樣如樓主所說,在1.4中Timestamp.compareTo(Date)的時候會調用繼承來的Date.compareTo(Date)方法來完成比較,而Date.compareTo(Date)在比較前會把參數造型成Date對象,因此可以完成比較;而在1.5中Timestamp則直接使用自己的Timestamp.compareTo(Date)方法來比較,并試圖在其中把參數造型成Timestamp,因此拋出造型異常。

    但是這并不像樓主想像的,“Generics也會帶來一些其他的問題”,而是sun有意為之。看上面這個compareTo方法的相關說明:

    // This forwarding method ensures that the compareTo(Date) method defined
    // in java.util.Date is not invoked on a Timestamp

    顯然sun認為1.4中的做法是不對的,下定決心在以放棄兼容性為代價在1.5中更正這個錯誤,而不是一個bug(真的要修復這個bug的話只要把上面這個方法刪掉就行了)。sun堅持的正好就是樓主說的原則問題:只比較具有相同類型的兩個對象

    放棄兼容性的代價就是有一些在1.4下面正常的代碼在1.5下面不能允許了,包括大名鼎鼎的JIRA。對此JIRA的反應是:

    JDK 1.5 has a bug that prevents JIRA from processing mail correctly. Until the issue is resolved, JIRA does not support JDK 1.5. We recommend you use JDK 1.4.x but it is possible to continue with JDK 1.5 by restarting the server with option \'-Dallow.jdk.1.5=true\'. You can find the JDK bug at http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5103041


    可是JIRA想要等“issue is resolved”那一天恐怕等不著了,這是個原則問題嘛 :)

    # re: 關于Generics的一點兒理解  回復  更多評論   

    2005-07-06 23:31 by Java求索
    多謝您的評論,我所說的其他問題所指的是Migration的問題。如果一個項目使用了1.4中的compareTo()方法,那么當這個項目要Migrate到1.5的時候,代碼就不能編譯通過了,必須修改源代碼才行。

    # re: 關于Generics的一點兒理解  回復  更多評論   

    2005-07-07 14:19 by emu
    可是你說的是泛形帶來的其他問題,而這個問題其實不是泛形帶來的。

    # re: 關于Generics的一點兒理解  回復  更多評論   

    2005-07-07 16:38 by david
    那可能是我的表達不太清楚。不過我的本意是說Migration的問題。謝謝你評論。

    # re: 關于Generics的一點兒理解  回復  更多評論   

    2005-07-08 12:05 by 文章千古事,得失寸心知
    >> 我想這是因為timestamp繼承了Date的CompareTo()方法,所以一個timestamp就可以與Date比較了,但是應用了Generics以后這種情況是不允許的,而且代碼也沒有特殊處理,因此就會有Exception了。看來Generics也會帶來一些其他的問題。

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


    網站導航:
     
    主站蜘蛛池模板: 日韩特黄特色大片免费视频| 亚洲中文无码mv| 热re99久久6国产精品免费| 久久精品亚洲综合| 精品少妇人妻AV免费久久洗澡| 美女被免费网站在线视频免费 | 亚洲国产精品无码专区在线观看| 9久9久女女免费精品视频在线观看| 国产a级特黄的片子视频免费| 亚洲综合激情五月色一区| 国产精品免费看久久久 | 亚洲高清资源在线观看| 91精品免费观看| 久久久无码精品亚洲日韩按摩| 日韩免费视频一区二区| 亚洲精选在线观看| 波多野结衣在线免费观看| 亚洲男人的天堂久久精品| 大学生一级特黄的免费大片视频| 亚洲国产成人久久精品大牛影视 | 在线精品亚洲一区二区| 蜜臀91精品国产免费观看| 香蕉视频在线观看免费| 国产精品亚洲а∨无码播放| 一区二区三区在线免费看| 亚洲宅男精品一区在线观看| 国产zzjjzzjj视频全免费 | 巨波霸乳在线永久免费视频| 最新亚洲春色Av无码专区| 亚洲国产成人精品无码久久久久久综合| 丁香六月婷婷精品免费观看| 亚洲国产高清在线| 永久黄网站色视频免费直播| 亚洲精品视频免费 | 亚洲av永久无码精品秋霞电影影院| 十八禁无码免费网站| 亚洲日韩国产二区无码| 国产偷国产偷亚洲高清日韩| 69xx免费观看视频| 一个人看的免费视频www在线高清动漫 | 黄页网址大全免费观看12网站|