Integer 中的 「==」 陷阱

先看一段代碼:
static boolean test(Integer a, Integer b) {

       return a == b;

  }

  public static void main(String[] args) {

       System. out.println( test(100, 100));  // 輸出 true 

       System. out.println( test(150, 150));  // 輸出 false

  }
test(100,100) 和 test(150,150)竟然輸出兩種徹底不一樣的結果!!這難道有什麼玄機嗎? 首先咱們肯定一點,"==" 在java中比較對象時永遠是比較對象的地址,這一點毫不會錯,問題確定出在其餘地方。
 
咱們來分析一下test方法執行過程當中到底發生了什麼。由於test的參數是Integer 類型,因此調用test的時候會隱式地作一次裝箱操做。例如 執行test(100,100),首先會執行下面兩句:Integer a = 100 ; Integer b = 100;而後在去執行方法體,比較 a 和 b 的地址是不是指向同一個對象。
 
由此看來,100 和 150 產生不一樣的結果,緣由確定出在自動裝箱上。由於 == 過程就是比較對象地址,這個地址是在自動裝箱時賦值的。那麼自動裝箱時到底發生了什麼呢?還好java 源碼是公開的。
 
Integer 在自動裝箱時調用了valueOf 方法,因此咱們來分析一下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 是個什麼東西?看名字咱們就知道,這個確定是和緩存相關的,看一下源碼也知道這個內部類確實是用來緩存Integer值的。默認緩存的Integer 值範圍是  -128 ~ 127 。
 
咱們來分析一下valueOf(int i)的執行過程:
若是 i 大於緩存中的 最小值(-127) 而且 小於 緩存中的最大值(127),直接返回IntegerCache 中緩存的Integer對象。不然就新建一個Integer對象並返回。
 
這下100 和  150 的區別就瞭然了吧。test(100,100)時,兩次裝箱操做後,a 和 b 都是指向緩存中的同一個對象,固然是返回true了。test(150,150) 就不同了,裝箱操做時都是返回新的Integer對象,== 操做時地址必然不相等,因此返回false。
 
之後遇到數字比較時,要麼先將值賦給對應的基本類型在比較,要麼比較包裝類型中的包裝值(例如 a.intValue() == b.intValue()),要麼直接調用equals方法。
相關文章
相關標籤/搜索