Effective Java 筆記(三)

來源:互聯網
上載者:User
相關讀書筆記列表NO.7 在改寫equals方法時請遵守通用約定
下列情況是不需要改寫equals方法的:1。同一個類的不同執行個體本質上是唯一的,就是個執行個體都有自己的本體(Identify)。2。不關心該類是否提供了邏輯相等的功能。3。父類已經改寫過equals方法,對於子類來說,繼承過來的equals方法已經是最合適的了。4。一個類是私人的或者是包可見的,且確定它的equals方法不會被調用。 對於需要改寫equals方法的時候,應該遵守如下約定:1。自反性,即x.equals(x)為true.2。對稱性,即若且唯若x.equals(y)為true時y.equals(x)也一定為true。3。傳遞性,即對任意的x,y,z,如果x.equals(y)為true,並且y.equals(z)也為true,那麼x.equals(z)也必須為true.4。一致性,即對於任意的x,y,如果x,y都沒有被修改的話,那麼多次調用x.equals(y)要麼一致地返回ture,要麼一致地返回false.5。對於非空的引用x,x.equals(null)一定要返回false. 改寫equals方法時的建議:1。用==操作符檢查實參是否為指向對象的同一個引用。2。使用instanceOf檢查實參是否是正確的類型。3。在2的基礎上,把實參轉換成正確的類型。4。檢查實參的域與當前對象的域值是否相等。5。編寫完equals方法後,檢查是否滿足等價關係。
例如:
  1. public boolean equals(Object o)
  2. {
  3.        if(o== this) return true;
  4.        if(!(o instanceof xxxx) return false;
  5.        xxx in = (xxx)o;
  6.        return ……..
  7. }
改寫equals方法的告誡:1、不要企圖讓equals方法做太多事。2、不要使equals依賴不可靠的資源,否則會違背一致性。3、不要將equals中的對象裝換為其他的類型。
4、要注意的時候不要提供這樣的方法public boolean equals(MyClass o)這樣是重載並不是覆蓋Object的equals方法。總結:不用重寫equals方法就盡量不要去找麻煩,確實需要改寫equals方法時,遵守通用約定,因為對象會在程式中不停的傳遞,所以可能會導致程式運行不正常,甚至崩潰而很難找到程式崩潰的原因。總之,還是遵守約定吧!

NO.8 改寫equals方法時必須覆蓋hashCode方法
      
這點必須切忌,不然在你和hash-based集合打交道的時候,錯誤就會出現了。關鍵問題在於一定要滿足相等的對象必須要有相等的hashCode。如
果你在PhoneNumber類中覆蓋了equals方法,但是沒有覆蓋hashCode方法,那麼當你做如下操作的時候就會出現問題了。

  1. Map m = new HashMap();
  2. m.put(new PhoneNumber(408,863,3334),”ming”)


你調用m.get(new
PhoneNumber(408,863,3334))的時候你希望得到ming但是你卻得到了null,為什麼呢因為在整個過程中有兩個
PhoneNumber的執行個體,一個是put一個是get,但是他們兩個邏輯相等的執行個體卻得到不同的hashCode那麼怎麼可以取得以前存入的ming
呢。

NO.9 總是要改寫toString()方法
        在Object的toString方法返回的形式是Class的類型加上@加上16進位的hashcode,非常難以理解。最好在自己的類中提供toString方法更好的表述執行個體的資訊,不然別人怎麼看得明白呢。
        在實際應用中,toString方法應該返回對象中包含的所有令人感興趣的資訊。同時,最好在程式中提供一個相匹配的建構函式或者靜態Factory 方法,便於程式員在對象和它的字串表示之間進行來迴轉換。
       在實現toString方法的時候,必須要做出是否在文檔中指定傳回值的格式的決定。指定格式可以被用來做為一種標準的,無二意性的表達形式,但這樣也會使字串的表示嵌入到永久資料中,如果以後改變了表達形式,則會影響到系統的代碼和資料。不管你是否決定指定格式,都應該在代碼中清晰的表明自己的意圖。可在所在的類中為toString傳回值中所包含的資訊提供一種編程訪問途徑,用來擷取toString方法返回字串中的資訊,避免程式員自己去解析字串而導致的錯誤。NO.10 謹慎地改寫clone(clone方法詳解請參見java clone方法使用詳解)      一個對象要想被Clone,那麼要實現Clone()介面,這個介面沒有定義任何的方法,但是如果你不實現這個介面的話,調用clone方法的
時候會出現CloneNotSupportedException,這就是作者叫做mixin的介面類型。通常clone()方法可以這樣覆蓋public Object clone()<br />{<br />try<br />{<br /> return super.clone();<br />}<br />catch(CloneNotSupportedException e)<br />{}<br />}  但是當你要clone的類裡面含有可修改的引用欄位的時候,那麼你一定要把整個類的藍圖進行複製,如果對你clone得到的對象進行修改的時候還會影響到原來的執行個體,那麼這是不可取的。所以應該這樣clone()

public Object clone() throws CloneNotSupportedException<br />{<br /> Stack Result = (Stack)super.clone();<br /> Result.elements = (Object[])elements.clone();<br /> Return result;<br />}其中elements是stack類中可修改的引用欄位,注意如果elements是final的話我們就無能為力了,因為不能給他重新賦值了.其實如果不是必須的話,根本就不用它最好。      clone方法如果實現得不當會給系統帶來隱藏的bug,如果非要使用類似的功能最好的辦法是提供某些其他的途徑(拷貝建構函式或者提供一個靜態Factory 方法來替代建構函式)來替代對象的拷貝,或者乾脆不提供這樣的能力。      Cloneable有很多問題,所以安全的說,其他的介面不應該擴充(extend)這個介面,並且為了繼承而設計的類也不應該實現(implement)這個介面。NO.11 考慮實現Comparable介面      compareTo方法是java.lang.Comparable介面中的唯一方法,它允許進行簡單的相等比較,也允許執行順序比較,一個類實現了comparable介面就表明他的執行個體具有內建的排序關係。Java平台庫中所有的值類都實現了Comparable。將當前對象與指定對象進行順序比較的時,返回負整數,0或者正整數(<、=、>),如果指定對象的類型無法進行比較,則拋出ClassCastException或者NullPointException異常,compareTo方法應遵守如下限制條件:自反性、對稱性、傳遞性和非空性的限制條件。在實現數值比較的compareTo方法時還要防止範圍溢出的情況。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.