<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
        最近做項目,在一次寫equals方法時突然悟出了一些心得,小記之,以備后用。在《Effective Java(第二版)》的Item7中提出我們要盡量避免重新equals方法,他同時也列舉了幾種我們不需要實現equals方法的情況:
    1)類的每個實例從本質上來說是唯一的,如Thread類的實例。
    2)我們并不會用到該類的equals方法,如Random類,雖然可以比較兩個Random的實例,以判斷兩個實例是否可以產生相同的隨機數,設計者認為這樣的需求用到的場合很少,因而就沒有重寫equals方法。
    3)父類已經實現了equals方法,并且父類實現方式和子類實現方式是一樣的,如大部分的Set實現的equals方法使用AbstractSet類提供的equals方法,List實現則使用AbstractList,Map實現使用AbstractMap的。
    4)一個private類或package-private類,我們自己可以確保我們不會使用到它們的equals方法。
    同時書也提出一般只有值類型的類才需要實現equals方法,像Date、Integer、Order(作為bean來使用)等。
    另外,我們在實現equals方法是也要遵循以下幾個原則:
    1)自反性(reflexive):x.equals(x)==true
    2)對稱性(symmetric):x.equals(y)==y.equals(x)
    3)傳遞性(transitive):若x.equals(y)==true, y.equals(z)==true,則x.equals(z)==true。
    4)一致性(consistent):多次調用x.equals(y)的結果應該是一樣的。
    5)對任何非null實例x,x.equals(null)==false。

    根據這些特性,我們可以寫出如下代碼:
     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類的代碼如下:
     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》這本書中,貌似equals實現方法前面沒有null、this的判斷,因為instanceof可以解決null的問題,而super.equals()方法可以解決this問題,但是我還是喜歡把它們都分出來,這樣寫的更加明了一些。另外,事實上,這里的實現并沒有遵循對稱性的原則,因為如果A是B的子類,而這個equals方法在A類中,那么AInstance.equals(BInstance)==false,若B也實現了類似的equals方法,則BInstance.equals(AInstance)==true(當A沒有新的比較字段時,或許這個時候A根本就不需要實現equals方法,如本文開頭列出的第三條),這是因為AInstance instanceof BInstance == true,反之則為false。不過由于這種情況并不常見,所以就不去care了。:)

        事實上,這里我之所以要記錄這些代碼,主要是因為有ObjectUtils類的存在。記得以前在學C#的時候,它的Object類提供了一個靜態的Equals方法,我一直對這個方法的存在感到很疑問,直到這次自己寫這個equals方法才弄明白,因為雖然在equals方法實現中,最后還要判斷類字段是否equals,然后這些字段都有可能是null的,如果沒有提供這個靜態的equals方法,我們就需要自己來判斷每個字段是否為null,然后才可以調用它的equals方法,這樣就比較麻煩了,而Object.Equals方法正是對這種行為的封裝,我們只要使用一個方法就可以安全的實現類成員的equals。這也是我加ObjectUtils類的意義所在。希望以后能有機會向這個ObjectUtils類填充更多的實用方法。:)

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

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

    比你代碼的通用性與可讀性都要好得多。  回復  更多評論
      
    # re: equals方法實現小記
    2011-06-29 23:10 | dirzy
    需求都不清晰就開始編碼?。。。!!!
    你覺得你有必要寫這個ObjectUtils類嘛?重復造垃圾輪子!  回復  更多評論
      
    # re: equals方法實現小記[未登錄]
    2011-06-29 23:30 | jim
    “不要以為讀過幾本黑手黨的書你就可以做黑社會老大,你試過被人用槍指著頭嘛?”

    不要以為讀過幾本稍微深入點的書,就開始想談什么架構!代碼都不多寫的架構師,架構個毛啊!最鄙視代碼都不寫的所謂的“架構師”。

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

    如果對commons的框架不太了解,可以去看看《Jakarta Commons Cookbook》(影印版),雖然版本老了些,但你仍會發現不少你未來可能會用到的工具的。  回復  更多評論
      
    # re: equals方法實現小記
    2011-06-30 22:18 | DLevin
    @Lancelot
    呵呵,見笑了,對commons里面的內容還真不了解,有計劃要好好研究一下那里的內容,可惜最近一直沒時間,多謝哈~~~~  回復  更多評論
      
    主站蜘蛛池模板: 久久国产精品免费专区| 成人一区二区免费视频| 无码免费午夜福利片在线 | 最近免费中文字幕高清大全| 国产午夜亚洲精品午夜鲁丝片| 一级一看免费完整版毛片| 国产成人A亚洲精V品无码| 在线观看免费无码视频| 亚洲an天堂an在线观看| 亚洲美女视频免费| 亚洲深深色噜噜狠狠网站| 日本免费高清一本视频| 香蕉视频免费在线| 亚洲熟妇无码八AV在线播放| 久久精品电影免费动漫| 亚洲av永久无码精品天堂久久| 岛国片在线免费观看| 黄色a级片免费看| 国产A在亚洲线播放| 免费看黄视频网站| 色天使亚洲综合一区二区| 亚洲色欲色欲www在线丝| 日韩插啊免费视频在线观看 | 亚洲码国产精品高潮在线| 久久99精品国产免费观看| 亚洲人成毛片线播放| 四虎永久在线精品免费观看地址| xvideos永久免费入口| 亚洲视频国产视频| 国产美女无遮挡免费网站| 三级网站在线免费观看| 亚洲六月丁香六月婷婷色伊人| 成人免费无码精品国产电影| 青柠影视在线观看免费高清 | 精品国产无限资源免费观看| 亚洲JIZZJIZZ妇女| 亚洲码国产精品高潮在线| 大地资源二在线观看免费高清| xxxxx做受大片在线观看免费| 亚洲伊人久久大香线蕉啊| 亚洲国模精品一区|