自己對Java中==與equals比較的理解

首先我們先看三個實例結果:

實例1:

String s1 = new String("abc");

String s2 = new String("abc");

s1==s2——結果爲false;

s1.equals(s2)——結果爲true;

實例2:

Object obj1 = new Object();

Object obj2 = new Object();

obj1==obj2;

obj1.equals(obj2);

結果都爲false;

示例3:

Object obj1 = new Object();

Object obj2 = obj1;

obj1==obj2;

obj1.equals(obj2);

結果都爲true;


看到這三種結果,雖然大家都知道這個結果,初學者可能難免都會產生一種說不清道不明感覺,下面是個人對==和equals兩種比較操作的理解,不對之處也請各們高手指正,以免我誤道初學者。

首先我來解說示例1:

先讓我們來看看String類equals方法的源碼:

public boolean equals(Object anObject) {
   if (this == anObject) {
      return true;
   }
   if (anObject instanceof String) {
      String anotherString = (String)anObject;
      int n = count;
      if (n == anotherString.count) {
         char v1[] = value;
         char v2[] = anotherString.value;
         int i = offset;
         int j = anotherString.offset;
         while (n-- != 0) {
            if (v1[i++] != v2[j++])
           return false;
         }
         return true;
      }
   }
   return false;
}



如上代碼所示,equals方法的第一步就是進行==比較,而我們知道,兩個String類型的==比較結果是false,所以我們繼續往下看代碼,當==結果爲false時,並且比較類型爲String時,就會把兩個String轉化爲char數組,通過比較char數組中的每個值來判斷最終結果。


再先我來解說示例2:

還是讓我們先看一段Object類equals方法的源碼:

 public boolean equals(Object obj) {
    return (this == obj);
 }


 

代碼所示,當兩個對象類型進行equals方法比較時,默認是進行==比較

這時大家可能會迷糊了,心裏就會想:

Object obj1 = new Object();

Object obj2 = new Object();

如果obj1與obj2兩個對象中的值完全一樣,爲什麼他們的==和equals都會返回false呢?想不通,不急,不妨看看我說的對不對

創建一個對象類型,如Object obj = new Object();在JVM中會開闢兩塊內存,一塊爲obj,在這我稱之爲變量內存(存儲在棧中),一塊爲new Object();在這裏我稱之爲對象內存(存儲在堆中);而變量僅僅只是對象的一個引用而已。

在上面的示例中我們創建了obj1與obj2兩個變量,分別在JVM中開闢了兩塊內存,同時並具有唯一內存地址,而當對象類型使用==進行比較時,恰恰就是比較的這兩個對象的內存地址值(內存地址的其中一種表示形式就是hashcode值),所以對象類型的==結果爲false。又因爲Object的equals默認就是進行==比較,所以對象類型的equals返回結果也是false;


有了示例2的解說,相信大家對示例3的結果應該會比較清楚了,因爲obj2=obj1,意味着new Object()不僅被obj1變量引用,同時還被obj2變量引用,所以,這兩個變量指向同一塊內存對象,所以他們的==和equals都爲true。

簡言之:

當比較的雙方爲基本數據類型時,==比較的是雙方的值。

當比較的雙方爲對象數據類型時,==和equals都比較的是雙方的變量所指向對象(值)的內存地址。

而通過示例1我們可以得出,引用類型的equals比較的是兩個對象的內容是否相等。

所以我們在判斷兩個對象是否相等時,需要重寫equals方法逐個判斷對象中的內容是否相等。

所以使用使用對象clone出來的對象,雙方==和equals也還是false,因爲當我們clone對象時,仍然是返回一個new Object(),源Object與clone出的Object具有不相同的內存地址。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章