Integer判等的陷阱:你知道Integer內部高速緩衝區IntegerCache嗎?

https://blog.csdn.net/magician_Code/article/details/51469101java

 

咱們先來看看下面代碼的運行狀況:緩存

public static void main(String[] args)
{
    // TODO Auto-generated method stub
    Integer integer1;
    Integer integer2;

    integer1 = new Integer(10);
    integer2 = new Integer(10);
    //第一次比較
    System.out.println("第一次比較:"+(integer1==integer2));

    //第二次比較
    System.out.println("第二次比較:"+(integer1==10));

    integer1 = 127;
    integer2 = 127;
    //第三次比較
    System.out.println("第三次比較:"+(integer1==integer2));

    integer1 = 128;
    integer2 = 128;
    //第四次比較
    System.out.println("第四次比較:"+(integer1==integer2));
}

運行程序,結果以下:

你看出了運行結果了嗎?spa

第一次和第二次比較就無可厚非了,第一次是直接把兩個不一樣的對象比較,固然是false;第二次比較時,是把Integer對象和int型10進行比較,根據自動裝箱、拆箱機制,這時候的比較就等價於10==10,因此是true。那麼後面兩個爲何會出現兩種不一樣的結果呢?.net

首先咱們先來看看Integer的兩種定義方式:

code

Integer integer1 = new Integer(10);
Integer integer2 = 10;

第一種是咱們常見的建立一個對象的方法,那麼第二個方法呢?根據Java的自動裝箱、拆箱機制,這時在Integer內部其實是作了以下操做:orm

Integer integer2 = Integer.valueOf(10);

這時咱們查看Integer源碼中關於valueOf方法的定義:對象

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

這裏咱們會留意到」IntegerCache」這個類,跟蹤一下代碼,發現這是Integer的一個私有內部類,聲明以下:blog

private static class IntegerCache
  {
    static final int low = -128;
    static final int high;
    static final Integer[] cache;

    private IntegerCache() {}

    static
    {
      int i = 127;
      String str = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
      if (str != null) {
        try
        {
          int j = Integer.parseInt(str);
          j = Math.max(j, 127);
          i = Math.min(j, 2147483518);
        }
        catch (NumberFormatException localNumberFormatException) {}
      }
      high = i;
      cache = new Integer[high - -128 + 1];
      int k = -128;
      for (int m = 0; m < cache.length; m++) {
        cache[m] = new Integer(k++);
      }
      assert (high >= 127);
    }
  }
}

這段代碼並不難讀,這裏類緩存了從-128到127之間的全部整型對象,意思是當使用自動裝箱的方式定義一個值在-128到127的Integer對象時,咱們獲得的是從緩存區(IntegerCache)中返回的實例。接口

因此,當咱們在進行上面的第三次比較時,此時的integer1和integer2是同一個對象,那麼比較的結果固然是true啦。第四次是由於咱們指定的值爲128,>127,因此Integer內部會建立新的對象返回,因此固然不可能相等。

ci

最後囉嗦一下,若是要進行兩個Integer對象基於數值的比較時,由於Integer實現了Compaeable接口,因此直接使用compaerTo方法進行比較會比較穩當。判等的話還可使用equals方法,因而咱們把最開始的代碼改爲以下:

public static void main(String[] args)
{
    // TODO Auto-generated method stub
    Integer integer1;
    Integer integer2;

    integer1 = new Integer(10);
    integer2 = new Integer(10);
    //第一次比較
    //System.out.println("第一次比較:"+(integer1==integer2));
    if(integer1.equals(integer2))
        System.out.println("第一次比較:"+true);
    else
        System.out.println("第一次比較:"+false);

    //第二次比較
    System.out.println("第二次比較:"+(integer1==10));

    integer1 = 127;
    integer2 = 127;
    //第三次比較
    //System.out.println("第三次比較:"+(integer1==integer2));
    if(integer1.equals(integer2))
        System.out.println("第三次比較:"+true);
    else
        System.out.println("第三次比較:"+false);

    integer1 = 128;
    integer2 = 128;
    //第四次比較
    //System.out.println("第四次比較:"+(integer1==integer2));
    if(integer1.equals(integer2))
        System.out.println("第四次比較:"+true);
    else
        System.out.println("第四次比較:"+false);
}
相關文章
相關標籤/搜索