程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> [Java開發之路](19)Long緩存問題

[Java開發之路](19)Long緩存問題

編輯:JAVA綜合教程

[Java開發之路](19)Long緩存問題


Long中有個小小的陷阱,就是在-128至127范圍內,Long.valueOf(long l)返回的Long的實例是相同的,而在此范圍之外每次使用valueOf(long l)時,返回的實例都是不同的。

舉例:


  1. System.out.println(Long.valueOf(-129) == Long.valueOf(-129)); // false
  2. System.out.println(Long.valueOf(-128) == Long.valueOf(-128)); // true
  3. System.out.println(Long.valueOf(127) == Long.valueOf(127)); // true
  4. System.out.println(Long.valueOf(128) == Long.valueOf(128)); // false
下面我們通過Long源碼進行分析一下:

  1. public static Long valueOf(long l) {
  2. final int offset = 128;
  3. if (l >= -128 && l <= 127) { // will cache
  4. return LongCache.cache[(int)l + offset];
  5. }
  6. return new Long(l);
  7. }

從上面代碼中我們可以看出先判斷傳遞過來的數值是否在[-128,127]之間,如果是則直接從緩存中返回對應的引用,否則新創建一個Long的實例。所以說如果不在這個區間范圍內,返回一個新創建的Long類型引用,用==判斷就會理所當然的返回false,地址不一樣。但是如果我們使用equals方法,則會返回true,數值是一樣的。


  1. Long.valueOf(128).equals(Long.valueOf(128)) // true

我們看看對於在區間范圍之內,是如何返回對應的引用?最重要的是Long類中有一個靜態的內部類LongCache,專門用於緩存-128至127之間的值。

 


  1. private static class LongCache {
  2. private LongCache(){}
  3.  
  4. static final Long cache[] = new Long[-(-128) + 127 + 1];
  5.  
  6. static {
  7. for(int i = 0; i < cache.length; i++)
  8. cache[i] = new Long(i - 128);
  9. }
  10. }

在LongCache類中定義了一個cache數組,來存儲緩存數據。我們可以看到cache數組的長度:-(-128) + 127 + 1,很明了的知道緩存數據從-128到127,後面的1代表數字0,一共256個元素。

valueOf這個方法設計比較好的一點是offset,它的初始值設為128,目的就是為了數組下標128處存放0,這樣就將正數和負數分隔開。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved