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

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

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

    上善若水
    In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
    posts - 146,comments - 147,trackbacks - 0
        最近做項(xiàng)目,在一次寫(xiě)equals方法時(shí)突然悟出了一些心得,小記之,以備后用。在《Effective Java(第二版)》的Item7中提出我們要盡量避免重新equals方法,他同時(shí)也列舉了幾種我們不需要實(shí)現(xiàn)equals方法的情況:
    1)類(lèi)的每個(gè)實(shí)例從本質(zhì)上來(lái)說(shuō)是唯一的,如Thread類(lèi)的實(shí)例。
    2)我們并不會(huì)用到該類(lèi)的equals方法,如Random類(lèi),雖然可以比較兩個(gè)Random的實(shí)例,以判斷兩個(gè)實(shí)例是否可以產(chǎn)生相同的隨機(jī)數(shù),設(shè)計(jì)者認(rèn)為這樣的需求用到的場(chǎng)合很少,因而就沒(méi)有重寫(xiě)equals方法。
    3)父類(lèi)已經(jīng)實(shí)現(xiàn)了equals方法,并且父類(lèi)實(shí)現(xiàn)方式和子類(lèi)實(shí)現(xiàn)方式是一樣的,如大部分的Set實(shí)現(xiàn)的equals方法使用AbstractSet類(lèi)提供的equals方法,List實(shí)現(xiàn)則使用AbstractList,Map實(shí)現(xiàn)使用AbstractMap的。
    4)一個(gè)private類(lèi)或package-private類(lèi),我們自己可以確保我們不會(huì)使用到它們的equals方法。
    同時(shí)書(shū)也提出一般只有值類(lèi)型的類(lèi)才需要實(shí)現(xiàn)equals方法,像Date、Integer、Order(作為bean來(lái)使用)等。
    另外,我們?cè)趯?shí)現(xiàn)equals方法是也要遵循以下幾個(gè)原則:
    1)自反性(reflexive):x.equals(x)==true
    2)對(duì)稱(chēng)性(symmetric):x.equals(y)==y.equals(x)
    3)傳遞性(transitive):若x.equals(y)==true, y.equals(z)==true,則x.equals(z)==true。
    4)一致性(consistent):多次調(diào)用x.equals(y)的結(jié)果應(yīng)該是一樣的。
    5)對(duì)任何非null實(shí)例x,x.equals(null)==false。

    根據(jù)這些特性,我們可以寫(xiě)出如下代碼:
     1 public class Customer implements Serializable {
     2     private static final long serialVersionUID = 1L;
     3     
     4     private String id;
     5     private String name;
     6     private String role;
     7     
     8     @Override
     9     public boolean equals(Object obj) {
    10         if(obj == null) {
    11             return false;
    12         }
    13         
    14         if(this == obj) {
    15             return true;
    16         }
    17         
    18         if(!(obj instanceof Customer)) {
    19             return false;
    20         }
    21         
    22         Customer other = (Customer)obj;
    23         return (ObjectUtils.equals(id, other.id) && 
    24                 ObjectUtils.equals(name, other.name) &&
    25                 ObjectUtils.equals(role, other.role));
    26     }
    27     
    28     public String getId() {
    29         return id;
    30     }
    31     public void setId(String id) {
    32         this.id = id;
    33     }
    34     public String getName() {
    35         return name;
    36     }
    37     public void setName(String name) {
    38         this.name = name;
    39     }
    40     public String getRole() {
    41         return role;
    42     }
    43     public void setRole(String role) {
    44         this.role = role;
    45     }
    46 }
    其中ObjectUtils類(lèi)的代碼如下:
     1 public class ObjectUtils {
     2     
     3     /**
     4      * Compare whether the left and right is equals
     5      * It has already considered the null case
     6      * 
     7      * @param left
     8      * @param right
     9      * @return
    10      */
    11     public static boolean equals(Object left, Object right) {
    12         if(left == null && right == null) {
    13             return true;
    14         }
    15         if(left == null && right != null) {
    16             return false;
    17         }
    18         return left.equals(right);
    19     }
    20 }
    在《Effective Java》這本書(shū)中,貌似equals實(shí)現(xiàn)方法前面沒(méi)有null、this的判斷,因?yàn)閕nstanceof可以解決null的問(wèn)題,而super.equals()方法可以解決this問(wèn)題,但是我還是喜歡把它們都分出來(lái),這樣寫(xiě)的更加明了一些。另外,事實(shí)上,這里的實(shí)現(xiàn)并沒(méi)有遵循對(duì)稱(chēng)性的原則,因?yàn)槿绻鸄是B的子類(lèi),而這個(gè)equals方法在A類(lèi)中,那么AInstance.equals(BInstance)==false,若B也實(shí)現(xiàn)了類(lèi)似的equals方法,則BInstance.equals(AInstance)==true(當(dāng)A沒(méi)有新的比較字段時(shí),或許這個(gè)時(shí)候A根本就不需要實(shí)現(xiàn)equals方法,如本文開(kāi)頭列出的第三條),這是因?yàn)锳Instance instanceof BInstance == true,反之則為false。不過(guò)由于這種情況并不常見(jiàn),所以就不去care了。:)

        事實(shí)上,這里我之所以要記錄這些代碼,主要是因?yàn)橛蠴bjectUtils類(lèi)的存在。記得以前在學(xué)C#的時(shí)候,它的Object類(lèi)提供了一個(gè)靜態(tài)的Equals方法,我一直對(duì)這個(gè)方法的存在感到很疑問(wèn),直到這次自己寫(xiě)這個(gè)equals方法才弄明白,因?yàn)殡m然在equals方法實(shí)現(xiàn)中,最后還要判斷類(lèi)字段是否equals,然后這些字段都有可能是null的,如果沒(méi)有提供這個(gè)靜態(tài)的equals方法,我們就需要自己來(lái)判斷每個(gè)字段是否為null,然后才可以調(diào)用它的equals方法,這樣就比較麻煩了,而Object.Equals方法正是對(duì)這種行為的封裝,我們只要使用一個(gè)方法就可以安全的實(shí)現(xiàn)類(lèi)成員的equals。這也是我加ObjectUtils類(lèi)的意義所在。希望以后能有機(jī)會(huì)向這個(gè)ObjectUtils類(lèi)填充更多的實(shí)用方法。:)

    PS:如一樓所說(shuō)在commons中的EqualsBuilder已經(jīng)實(shí)現(xiàn)了相同的功能,而且代碼更加完善,有興趣的可以看看那里的代碼,我這里只是對(duì)這次新的的記錄,代碼只是對(duì)當(dāng)前我考慮的場(chǎng)景中使用,并沒(méi)有考慮其他方面。另外,在《Effective Java》中也是建議equals和hashCode兩個(gè)方法應(yīng)該是同時(shí)實(shí)現(xiàn)的,一樓也有說(shuō)可以用HashCodeBuider來(lái)實(shí)現(xiàn),這個(gè)大家也不妨可以去看看里面的源碼,最近時(shí)間不多,以后回來(lái)再看。。。。。。
    posted on 2011-06-29 19:05 DLevin 閱讀(2731) 評(píng)論(10)  編輯  收藏 所屬分類(lèi): Core Java

    FeedBack:
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-29 22:27 | Lancelot
    你這么大費(fèi)周章的寫(xiě)這么多代碼是大可不必的。
    不要寫(xiě)這個(gè)“ObjectUtils ”了,只要用commons的“EqualsBuilder”就好了。
    而且,既然你重寫(xiě)了equals方法,那就最好也重寫(xiě)hashCode方法(也有工具:“HashCodeBuilder”)。

    比你代碼的通用性與可讀性都要好得多。  回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-29 23:10 | dirzy
    需求都不清晰就開(kāi)始編碼?。。。!!!
    你覺(jué)得你有必要寫(xiě)這個(gè)ObjectUtils類(lèi)嘛?重復(fù)造垃圾輪子!  回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記[未登錄](méi)
    2011-06-29 23:30 | jim
    “不要以為讀過(guò)幾本黑手黨的書(shū)你就可以做黑社會(huì)老大,你試過(guò)被人用槍指著頭嘛?”

    不要以為讀過(guò)幾本稍微深入點(diǎn)的書(shū),就開(kāi)始想談什么架構(gòu)!代碼都不多寫(xiě)的架構(gòu)師,架構(gòu)個(gè)毛啊!最鄙視代碼都不寫(xiě)的所謂的“架構(gòu)師”。

    年輕人做技術(shù)要腳踏實(shí)地,話說(shuō)的有些重。接受不了的,當(dāng)我沒(méi)說(shuō)。。。  回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-30 00:28 | DLevin
    @Lancelot
    從開(kāi)始看Java開(kāi)始,一直認(rèn)為apache是一個(gè)偉大的組織,里面有很多我們能想得到的工具和框架。有打算以后花一段時(shí)間好好研究一下里面的代碼。這里的代碼只是對(duì)自己經(jīng)歷的一種記錄,無(wú)他~~~
    BTW:這兩個(gè)方法我確實(shí)也是不知道的,學(xué)習(xí)了~~~~  回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-30 00:33 | 過(guò)路客
    18 if(obj instanceof Customer) {
    19 return false;
    20 }
    這幾句代碼有問(wèn)題有問(wèn)題,另外還不明白你所說(shuō)得架構(gòu)師,現(xiàn)在架構(gòu)也被濫用了么
      回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-30 00:41 | DLevin
    @jim
    呵呵,雖然對(duì)第二段的表達(dá)方式不怎么贊同,但是你的觀點(diǎn)我還是非常認(rèn)同的,其實(shí)我從來(lái)沒(méi)有認(rèn)為我是一個(gè)架構(gòu)師,雖然我一直在往這個(gè)方向努力,不過(guò)還有好長(zhǎng)一段路要走,事實(shí)上,我現(xiàn)在都在避免談?wù)撐抑暗哪嵌谓?jīng)歷(這篇文章是沒(méi)多想就寫(xiě)上了,呵呵)  回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-30 00:55 | DLevin
    @過(guò)路客
    嗯,是寫(xiě)錯(cuò)了,多謝哈,架構(gòu)那事就不用再提了,算我筆誤,嘿嘿~~~  回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-30 08:54 | 窩窩影視
    架構(gòu) 沒(méi)啥關(guān)系  回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-30 11:05 | Lancelot
    @DLevin
    EqualsBuilder/ HashCodeBuilder不是方法,都是工具類(lèi),commons里還有大量類(lèi)工具類(lèi),如果是基本的底層功能你都可以從commons里面去翻翻看。

    如果對(duì)commons的框架不太了解,可以去看看《Jakarta Commons Cookbook》(影印版),雖然版本老了些,但你仍會(huì)發(fā)現(xiàn)不少你未來(lái)可能會(huì)用到的工具的。  回復(fù)  更多評(píng)論
      
    # re: equals方法實(shí)現(xiàn)小記
    2011-06-30 22:18 | DLevin
    @Lancelot
    呵呵,見(jiàn)笑了,對(duì)commons里面的內(nèi)容還真不了解,有計(jì)劃要好好研究一下那里的內(nèi)容,可惜最近一直沒(méi)時(shí)間,多謝哈~~~~  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 亚洲伊人久久大香线蕉影院| 无码天堂va亚洲va在线va| 日本亚洲免费无线码| 亚洲熟妇AV日韩熟妇在线| 亚洲精品无码99在线观看| 久操视频免费观看| 亚洲乱人伦中文字幕无码| 中文字幕无码精品亚洲资源网| 91精品国产免费入口| 亚洲AV无码一区二区三区鸳鸯影院| 最新国产AV无码专区亚洲 | 95老司机免费福利| 麻豆一区二区三区蜜桃免费| 亚洲AV无码一区二区二三区入口 | 国产亚洲精品a在线无码| 妻子5免费完整高清电视| 一级特黄色毛片免费看| 亚洲制服丝袜一区二区三区| 亚洲国产婷婷综合在线精品| 一色屋成人免费精品网站| 成人免费ā片在线观看| 亚洲中文字幕乱码一区| 亚洲韩国—中文字幕| 无码专区一va亚洲v专区在线| 亚洲一级免费视频| 青青操视频在线免费观看| 亚洲av日韩av永久在线观看| 香蕉蕉亚亚洲aav综合| 免费人成网站在线高清| 午夜宅男在线永久免费观看网| 中文字幕高清免费不卡视频| 亚洲AV无码一区二区一二区| 亚洲韩国在线一卡二卡| 亚洲一区二区三区香蕉| 国产又粗又长又硬免费视频| 最近高清中文字幕无吗免费看| 本免费AV无码专区一区| 人人爽人人爽人人片av免费| 亚洲精华国产精华精华液网站| 亚洲国产美女精品久久| 亚洲韩国—中文字幕|