<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 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    關(guān)于Generics的一點(diǎn)兒理解

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

    JDK5.0已經(jīng)release很久了,但一直沒(méi)機(jī)會(huì)好好學(xué)習(xí)一下,今天可有機(jī)會(huì)了。

    先來(lái)看一段代碼:

    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分別編譯就會(huì)出現(xiàn)不同的結(jié)果。先來(lái)說(shuō)用1.4編譯的情況:首先用1.4編譯,編譯器不會(huì)報(bào)錯(cuò),如果運(yùn)行的話,前面兩個(gè)輸出語(yǔ)句會(huì)分別打印“0,0”,而第三個(gè)會(huì)throw一個(gè)ClassCast exception. 因?yàn)镈ate不能與object比較,但是為什么能編譯通過(guò)呢?察看JDK源代碼就可以知道了,Date實(shí)現(xiàn)了Comparable接口,這個(gè)接口中的CompareTo()方法的參數(shù)就是Object。所以Date也不得不有一個(gè)以O(shè)bject為參數(shù)的CompareTo()方法,但是這個(gè)方法是沒(méi)有意義的,Date應(yīng)該與Date比較,所以Date這個(gè)Class里面就出現(xiàn)了兩個(gè)ComparaTo方法,一個(gè)是以Date為參數(shù),另一個(gè)是以O(shè)bject為參數(shù),這是1.4以前,不得不采用的方法。不然Date就沒(méi)法實(shí)現(xiàn)Comparable接口了。

    JDK1.5中Generics的出現(xiàn)解決了這個(gè)問(wèn)題,如果看1.5中Date類的源代碼的話,就會(huì)發(fā)現(xiàn)它只有一個(gè)CompareTo()方法了,那它怎么來(lái)實(shí)現(xiàn)Comparable接口呢,這就是Generics的功勞了。在Date聲明時(shí),實(shí)現(xiàn)Comparable接口是這么寫(xiě)的:...Comparable...,并且Comparable接口的聲明是這樣的:Comparable。這個(gè)T代表Type。它可以是任何Object。Comparable的實(shí)現(xiàn)類只要說(shuō)明T是什么具體類型就可以了。因此,Date就可以只有一個(gè)CompareTo()方法,又可以實(shí)現(xiàn)Comparable接口了。如果用1.5編譯上面的Code的話,就會(huì)發(fā)現(xiàn)這段Code是不能編譯通過(guò)的,編譯器會(huì)提示“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中出現(xiàn)的問(wèn)題。我想如果使用了1.5以后咱們編寫(xiě)代碼時(shí),出現(xiàn)ClassCastException的幾率就會(huì)很小了,因?yàn)榫幾g器會(huì)替你發(fā)現(xiàn)這樣的錯(cuò)誤。

    這就是Generics的好處了。

    但是還有一點(diǎn)值得考慮,如果我們?nèi)サ翦e(cuò)誤的那一行代碼,在1.5中編譯然后運(yùn)行,會(huì)發(fā)現(xiàn)還有地方與1.4的不同。第一行輸出語(yǔ)句會(huì)打印1,而不是0,這說(shuō)明1.5認(rèn)為具有相同時(shí)間的timestamp和date是不同的,但1.4認(rèn)為它們相同。我有看了一下1.5和1.4的源代碼,發(fā)現(xiàn)它們CompareTo(Date ...)的實(shí)現(xiàn)方法是不一樣的,可能問(wèn)題就出現(xiàn)在這里。我沒(méi)有試著去讀它的代碼,等有時(shí)間,一定好好研究一下。

    最后,還有一個(gè)問(wèn)題,如果用1.5編譯并運(yùn)行,會(huì)throw一個(gè)ClassCastException,而用1.4則不會(huì)出現(xiàn)這個(gè)問(wèn)題。我想這是因?yàn)閠imestamp繼承了Date的CompareTo()方法,所以一個(gè)timestamp就可以與Date比較了,但是應(yīng)用了Generics以后這種情況是不允許的,而且代碼也沒(méi)有特殊處理,因此就會(huì)有Exception了。看來(lái)Generics也會(huì)帶來(lái)一些其他的問(wèn)題。

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


    評(píng)論

    # re: 關(guān)于Generics的一點(diǎn)兒理解  回復(fù)  更多評(píng)論   

    2005-07-06 18:27 by emu
    這是jdk1.5一個(gè)已經(jīng)報(bào)告的bug:
    http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5103041


    問(wèn)題在于在jdk1.5中Timestamp多定義了一個(gè)比較方法:

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

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

    但是這并不像樓主想像的,“Generics也會(huì)帶來(lái)一些其他的問(wèn)題”,而是sun有意為之。看上面這個(gè)compareTo方法的相關(guān)說(shuō)明:

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

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

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

    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”那一天恐怕等不著了,這是個(gè)原則問(wèn)題嘛 :)

    # re: 關(guān)于Generics的一點(diǎn)兒理解  回復(fù)  更多評(píng)論   

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

    # re: 關(guān)于Generics的一點(diǎn)兒理解  回復(fù)  更多評(píng)論   

    2005-07-07 14:19 by emu
    可是你說(shuō)的是泛形帶來(lái)的其他問(wèn)題,而這個(gè)問(wèn)題其實(shí)不是泛形帶來(lái)的。

    # re: 關(guān)于Generics的一點(diǎn)兒理解  回復(fù)  更多評(píng)論   

    2005-07-07 16:38 by david
    那可能是我的表達(dá)不太清楚。不過(guò)我的本意是說(shuō)Migration的問(wèn)題。謝謝你評(píng)論。

    # re: 關(guān)于Generics的一點(diǎn)兒理解  回復(fù)  更多評(píng)論   

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

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 中文字幕不卡免费高清视频| 91精品国产免费久久国语蜜臀 | 亚洲av无码国产精品色在线看不卡| 无码日韩人妻AV一区免费l | 亚洲mv国产精品mv日本mv| 成人免费视频国产| 韩日电影在线播放免费版| 亚洲91精品麻豆国产系列在线| 日日夜夜精品免费视频| 免费观看男人吊女人视频| 亚洲日韩一区二区一无码| 在线亚洲精品自拍| 希望影院高清免费观看视频| 又粗又长又爽又长黄免费视频| 亚洲小说图片视频| 亚洲日韩精品一区二区三区| 女人被免费视频网站| 99热在线精品免费播放6| 菠萝菠萝蜜在线免费视频| 亚洲性色高清完整版在线观看| 国产亚洲精品成人a v小说| 欧美a级在线现免费观看| 免费无码一区二区三区蜜桃| 亚洲国产成人久久精品大牛影视 | 亚洲性色精品一区二区在线| 亚洲精品色午夜无码专区日韩| 在线免费观看色片| 性无码免费一区二区三区在线| 免费无码AV一区二区| 亚洲AV色吊丝无码| 亚洲第一精品在线视频| 亚洲综合伊人久久综合| 宅男666在线永久免费观看| 桃子视频在线观看高清免费完整| 国产亚洲免费的视频看| 一级毛片免费播放男男| AV激情亚洲男人的天堂国语| 亚洲熟妇无码AV不卡在线播放| 亚洲黄网在线观看| 亚洲国产精品久久久久久| 国产午夜亚洲精品午夜鲁丝片 |