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;还是构造函数?