String物件的equals()與 = =

Diy_os發表於2015-11-06
最近看了網上有人說,String物件的equals()與==的區別,不知道兩者到底有什麼區別,如果真的要徹底搞清楚,我們還是從“萬類之源”說起,http://blog.itpub.net/29876893/viewspace-1819489/這是之前寫關於Object的一篇文章,現在我們還是從原始碼入手(當然結合API更好)。
下面還是分析Object類中的equals()方法,關於原始碼如何獲取上篇文章已經說的很清楚。

下面是Object類中的equals():

點選(此處)摺疊或開啟

  1. public boolean equals(Object obj) {
  2.         return (this == obj);
  3.     }


  4.     /**
  5.      * Creates and returns a copy of this object. The precise meaning
  6.      * of "copy" may depend on the class of the object. The general
  7.      * intent is that, for any object {@code x}, the expression:
  8.      *

  9.      *
    			
  10.      * x.clone() != x
  11.      * will be true, and that the expression:
  12.      *

  13.      *
    			
  14.      * x.clone().getClass() == x.getClass()
  15.      * will be {@code true}, but these are not absolute requirements.
  16.      * While it is typically the case that:
  17.      *

  18.      *
    			
  19.      * x.clone().equals(x)
  20.      * will be {@code true}, this is not an absolute requirement.
  21.      *


  22.      * By convention, the returned object should be obtained by calling
  23.      * {@code super.clone}. If a class and all of its superclasses (except
  24.      * {@code Object}) obey this convention, it will be the case that
  25.      * {@code x.clone().getClass() == x.getClass()}.
  26.      *


  27.      * By convention, the object returned by this method should be independent
  28.      * of this object (which is being cloned). To achieve this independence,
  29.      * it may be necessary to modify one or more fields of the object returned
  30.      * by {@code super.clone} before returning it. Typically, this means
  31.      * copying any mutable objects that comprise the internal "deep structure"
  32.      * of the object being cloned and replacing the references to these
  33.      * objects with references to the copies. If a class contains only
  34.      * primitive fields or references to immutable objects, then it is usually
  35.      * the case that no fields in the object returned by {@code super.clone}
  36.      * need to be modified.
  37.      *


  38.      * The method {@code clone} for class {@code Object} performs a
  39.      * specific cloning operation. First, if the class of this object does
  40.      * not implement the interface {@code Cloneable}, then a
  41.      * {@code CloneNotSupportedException} is thrown. Note that all arrays
  42.      * are considered to implement the interface {@code Cloneable} and that
  43.      * the return type of the {@code clone} method of an array type {@code T[]}
  44.      * is {@code T[]} where T is any reference or primitive type.
  45.      * Otherwise, this method creates a new instance of the class of this
  46.      * object and initializes all its fields with exactly the contents of
  47.      * the corresponding fields of this object, as if by assignment; the
  48.      * contents of the fields are not themselves cloned. Thus, this method
  49.      * performs a "shallow copy" of this object, not a "deep copy" operation.
  50.      *


  51.      * The class {@code Object} does not itself implement the interface
  52.      * {@code Cloneable}, so calling the {@code clone} method on an object
  53.      * whose class is {@code Object} will result in throwing an
  54.      * exception at run time.
  55.      *
  56.      * @return a clone of this instance.
  57.      * @exception CloneNotSupportedException if the object's class does not
  58.      * support the {@code Cloneable} interface. Subclasses
  59.      * that override the {@code clone} method can also
  60.      * throw this exception to indicate that an instance cannot
  61.      * be cloned.
  62.      * @see java.lang.Cloneable
  63.      */
從上面我們可以看出來,比較的是兩個物件的地址值,更全面的介紹,自己看下上面的 註釋。

下面看下toString()方法,當然和本篇沒有多少關係。

點選(此處)摺疊或開啟

  1. public String toString() {
  2.         return getClass().getName() + "@" + Integer.toHexString(hashCode());
  3.     }

  4.     
返回的是包名.類名@十六進位制的雜湊值




下面看一小程式:

上面結果也許你會問,不都是字串麼!為什麼結果不一樣呢!?這個要結合java記憶體來分析,對於new出來的物件,是在堆中分配記憶體空間,而對於String類很特殊,
如果對於直接String ss = xxxx,是在常量池中分配記憶體空間,並不是在棧中分配。但是對於上述的a,b在棧中分配空間,指向了堆中不同的記憶體空間,當然兩者不等!

再看一個小程式:



咦,equals()不是比較的是地址麼?還是true,不能有這種定向思維,應該查閱API或者看下原始碼:

點選(此處)摺疊或開啟

  1. */
  2.     public boolean equals(Object anObject) {
  3.         if (this == anObject) {
  4.             return true;
  5.         }
  6.         if (anObject instanceof String) {
  7.             String anotherString = (String) anObject;
  8.             int n = value.length;
  9.             if (n == anotherString.value.length) {
  10.                 char v1[] = value;
  11.                 char v2[] = anotherString.value;
  12.                 int i = 0;
  13.                 while (n-- != 0) {
  14.                     if (v1[i] != v2[i])
  15.                             return false;
  16.                     i++;
  17.                 }
  18.                 return true;
  19.             }
  20.         }
  21.         return false;
  22.     }
上面很清楚,String類重寫了Object中的toString()方法,如果不是指向同一物件的話,那就比較內容是不是一樣,所以上文中a.equals(b),b.equals(a)返回的是true.
在繼承父類時,重寫某個方法很重要。上文中沒有說Object類中一個也很重要的方法hashcode(),這也是後續文章會寫。文章作為本人學習總結,如有錯誤之處,請指正!謝謝。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29876893/viewspace-1823819/,如需轉載,請註明出處,否則將追究法律責任。

相關文章