Long中有個小小的陷阱,就是在-128至127范圍內,Long.valueOf(long l)返回的Long的實例是相同的,而在此范圍之外每次使用valueOf(long l)時,返回的實例都是不同的。
舉例:
~~~
System.out.println(Long.valueOf(-129) == Long.valueOf(-129)); // false
System.out.println(Long.valueOf(-128) == Long.valueOf(-128)); // true
System.out.println(Long.valueOf(127) == Long.valueOf(127)); // true
System.out.println(Long.valueOf(128) == Long.valueOf(128)); // false
~~~
下面我們通過Long源碼進行分析一下:
~~~
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);
}
~~~
從上面代碼中我們可以看出先判斷傳遞過來的數值是否在[-128,127]之間,如果是則直接從緩存中返回對應的引用,否則新創建一個Long的實例。所以說如果不在這個區間范圍內,返回一個新創建的Long類型引用,用==判斷就會理所當然的返回false,地址不一樣。但是如果我們使用equals方法,則會返回true,數值是一樣的。
~~~
Long.valueOf(128).equals(Long.valueOf(128)) // true
~~~
我們看看對于在區間范圍之內,是如何返回對應的引用?最重要的是Long類中有一個靜態的內部類LongCache,專門用于緩存-128至127之間的值。
~~~
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);
}
}
~~~
在LongCache類中定義了一個cache數組,來存儲緩存數據。我們可以看到cache數組的長度:-(-128) + 127 + 1,很明了的知道緩存數據從-128到127,后面的1代表數字0,一共256個元素。
?valueOf這個方法設計比較好的一點是offset,它的初始值設為128,目的就是為了數組下標128處存放0,這樣就將正數和負數分隔開。
- 前言
- [Hibernate開發之路](1)Hibernate配置
- [Hibernate開發之路](2)Hibernate問題
- [Hibernate開發之路](3)基礎配置
- [Hibernate開發之路](4)ID生成策略
- [Hibernate開發之路](5)聯合主鍵
- [設計模式實踐之路](1)單例模式
- [Java]UDP通信的簡單例子
- [Java]套接字地址InetAddress講解
- [Java開發之路](1)final關鍵字
- [Java開發之路](2)Java字符串
- [Java開發之路](3)Java常用類
- [Java開發之路](4)String、StringBuffer與StringBuilder詳解
- [Java開發之路](5)異常詳解
- [Java開發之路](6)File類的使用
- [Java開發之路](7)RandomAccessFile類詳解
- [Java開發之路](8)輸入流和輸出流
- [Java開發之路](9)對象序列化與反序列化
- [Java開發之路](10)DOM解析XML文檔
- [Java開發之路](11)SAX解析XML文檔
- [Java開發之路](12)JDOM和DOM4J解析XML文檔
- [Java開發之路](14)反射機制
- [Java開發之路](15)注解
- [Java開發之路](16)學習log4j日志
- [Java開發之路](18)關于Class.getResource和ClassLoader.getResource的路徑問題
- [Java開發之路](19)Long緩存問題
- [Java開發之路](20)try-with-resource 異常聲明
- [Java開發之路](21)Comparator與Comparable
- [Java]Java工程師成神之路
- [細說Java](1)圖說字符串的不變性
- [細說Java](2)Java中字符串為什么是不可變的
- [細說Java](3)創建字符串是使用&quot; &quot;還是構造函數?