java java.lang.Long詳解之二 緩存

文章看事後感受受益不淺,因此留下了以備溫故: http://www.congmo.net/blog/2012/03/05/Long-toString/

衆所周知Long中有個小小的陷阱,就是在-128至127範圍內,Long.valueOf(long l)返回的Long的實例是相同的,而在此範圍以外每次使用valueOf(long l)時,返回的實例都是不一樣的。本篇文章的主要目的就是揭示這個小陷阱。java

首先來看一段代碼,驗證上述的小陷阱。
程序員

System.out.println(Long.valueOf(128) == Long.valueOf(128));
System.out.println(Long.valueOf(127) == Long.valueOf(127));
輸出結果:
false
true

像變魔術同樣,揭開以後就會以爲異常簡單。這裏也是一樣的道理。上兩段代碼,明白人一看便知。
數組

private static class LongCache {
  private LongCache(){}
  static final Long cache[] = new Long[-(-128) + 127 + 1];
  static {
    for(int i = 0; i < cache.length; i++)
      cache[i] = new Long(i - 128);
  }
}
public static Long valueOf(long l) {
  final int offset = 128;
  if (l >= -128 && l <= 127) { // will cache
    return LongCache.cache[(int)l + offset];
  }
  return new Long(l);
}

其實在Long中有一個靜態的內部類LongCache,專門用於緩存-128至127之間的值。說到這裏,不得不讚美一下寫這個方法的做者,很是很是用心啊,看看cache這個數組的長度:-(-128) + 127 + 1.就是想告訴閱讀這段代碼的人,我是從-128開始,正數最大爲127,而後後面的1表明數字0。一共256個元素。緩存

若是僅僅是緩存下來而不去使用那麼就沒有任何意義。valueOf(long l)就是使緩存派上用場的方法,它會判斷傳入的參數是否在-128-127之間,若是是則直接從緩存中返回對應的引用,不然新建立一個Long的實例。valueOf這個方法我以爲比較好的一處是offset,它的初始值設爲128,仔細想一想,cache128其實存放的是0,這樣就將正數和負數分隔開,並且針對-128-127之間的任何數做爲參數傳入都不須要作任何特殊處理,只要返回LongCache.cache(int)l + offset;便可,正負通吃。spa

程序員真的好奇怪,每當看到精巧的代碼時,都會有種賞心悅目的感受。我喜歡Long這個類,到處是寶!.net

相關文章
相關標籤/搜索