1. 程式人生 > >==和equals的區別,原始碼解析

==和equals的區別,原始碼解析

這是Object類裡面的equals方法原始碼:

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

看著還是用==在比較,原因分析:在大部分的封裝類中,都重寫了Object類的這個方法,所以兩者還是會有區別的。總的來說,==是一個關係運算符,如果比較的兩端都為基本型別,則判斷兩者的值是否相等,(判斷過程中還有不同基本型別的轉化),如果比較的兩端都為引用型別的話,則比較兩者所指向物件的地址是否相同;對於equals方法,首先,能呼叫這個方法肯定是一個物件,然後,如果這個物件所在的類重寫了equals方法,則按照重寫的方法進行比較,如果沒有,則比較兩者所指向物件的地址是否相同。

我們以Integer類的equals()方法的原始碼的詳細實現過程說明:

Integer重寫了equals方法如下(加註解):

public boolean equals(Object obj) {
        if (obj instanceof Integer) { //判斷傳進來的引數是不是Integer類的一個例項,
        如果不是直接返回false;
        return value == ((Integer)obj).intValue();//如果是,則判斷兩者的成員變數
        value值是不是相等的,這塊又回到了基本型別的比較。value的值在建立這個物件的時候
        被賦值。
        }
        return false;
    }

上面的原始碼可知,equals方法又呼叫了一個intValue方法,繼續檢視intValue方法原始碼:

 public int intValue() {
        return value;
    }

又因為在Integer類的例項在建立的時候還會呼叫valueOf方法自動裝箱,例如java在編譯Integer i = 100 ;時,會翻譯成為Integer i = Integer.valueOf(100);在Integer類中,valueOf方法是這麼實現的:

public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

上面這段程式碼首先規定了一個範圍,預設IntegerCache.low 是-127,Integer.high是128,如果引數中的i在這個範圍之內,則返回一個數組中的內容,如果不在這個範圍,則new一個新的Integer物件並返回,相當於把-128~127之間的數進行了快取,如果i這個範圍內 ,直接從快取中取,就不會new了,否則new一個新的Integer物件並返回。檢視Integer類的原始碼可以發現,這個數組裡面快取了基本型別-128-127之間的Integer物件

總的來說:
==比較地址,equals比較值,但是對於包裝類和基本型別,還要涉及它們的自動裝箱、自動拆箱,所以小心一點還是比較好的:

  1. Integer 型別的值在[-128,127] 期間,Integer 用 ==是可以的 , Integer 與 int 型別比較的是值。

  2. 如果要比較Integer的值,比較靠譜的是通過Integer.intValue();這樣出來的就是int值,就可以直接比較了;或者equals()比較