描述
首先,这里应该声明一下,Long等对象类型判断是否相等,采用Long == Long这种形式是错误的。
可以采用以下方式:
Long left = 100L;
Long right = 100L;
// 方法1:
System.out.println(left.doubleValue() == right.doubleValue());
// 方法2:
System.out.println(left.compareTo(right));
输出结果:
true
0
实验1
如果你亲自操刀,动手做了以下实验,也许你会突然得到一个让你困惑的结果:
Long left = 100L;
Long right = 100L;
System.out.println(left == right);
输出结果:
true
没错,采用 == 竟然也能得出true,也许这时候你可能会误以为jvm在自动拆箱(我以前也是这样以为,有点小白!!!)。
实验2
那么请你再做下面这个实验:
Long left = 1000L;
Long right = 1000L;
// 方法1:
System.out.println(left.doubleValue() == right.doubleValue());
// 方法2:
System.out.println(left.compareTo(right));
// 错误的方法:
System.out.println(left == right);
输出结果
true
0
false
等会,什么情况,怎么又为false?
实验3
不急,再做一个实验。
for (int i = -200; i < 200; i++) {
Long left = Long.valueOf(i);
Long right = Long.valueOf(i);
System.out.println("Long left = " + i + ", Long right = " + i
+ ", left == right :" + (left == right));
}
输出结果
Long left = -200, Long right = -200, left == right :false
Long left = -199, Long right = -199, left == right :false
Long left = -198, Long right = -198, left == right :false
...
Long left = -131, Long right = -131, left == right :false
Long left = -130, Long right = -130, left == right :false
Long left = -129, Long right = -129, left == right :false
Long left = -128, Long right = -128, left == right :true
Long left = -127, Long right = -127, left == right :true
Long left = -126, Long right = -126, left == right :true
Long left = -125, Long right = -125, left == right :true
Long left = -124, Long right = -124, left == right :true
Long left = -123, Long right = -123, left == right :true
Long left = -122, Long right = -122, left == right :true
Long left = -121, Long right = -121, left == right :true
Long left = -120, Long right = -120, left == right :true
Long left = -119, Long right = -119, left == right :true
Long left = -118, Long right = -118, left == right :true
Long left = -117, Long right = -117, left == right :true
Long left = -116, Long right = -116, left == right :true
Long left = -115, Long right = -115, left == right :true
Long left = -114, Long right = -114, left == right :true
Long left = -113, Long right = -113, left == right :true
Long left = -112, Long right = -112, left == right :true
Long left = -111, Long right = -111, left == right :true
Long left = -110, Long right = -110, left == right :true
...
Long left = -5, Long right = -5, left == right :true
Long left = -4, Long right = -4, left == right :true
Long left = -3, Long right = -3, left == right :true
Long left = -2, Long right = -2, left == right :true
Long left = -1, Long right = -1, left == right :true
Long left = 0, Long right = 0, left == right :true
Long left = 1, Long right = 1, left == right :true
Long left = 2, Long right = 2, left == right :true
Long left = 3, Long right = 3, left == right :true
Long left = 4, Long right = 4, left == right :true
Long left = 5, Long right = 5, left == right :true
Long left = 6, Long right = 6, left == right :true
Long left = 7, Long right = 7, left == right :true
Long left = 8, Long right = 8, left == right :true
Long left = 9, Long right = 9, left == right :true
Long left = 10, Long right = 10, left == right :true
...
Long left = 120, Long right = 120, left == right :true
Long left = 121, Long right = 121, left == right :true
Long left = 122, Long right = 122, left == right :true
Long left = 123, Long right = 123, left == right :true
Long left = 124, Long right = 124, left == right :true
Long left = 125, Long right = 125, left == right :true
Long left = 126, Long right = 126, left == right :true
Long left = 127, Long right = 127, left == right :true
Long left = 128, Long right = 128, left == right :false
Long left = 129, Long right = 129, left == right :false
Long left = 130, Long right = 130, left == right :false
Long left = 131, Long right = 131, left == right :false
Long left = 132, Long right = 132, left == right :false
Long left = 133, Long right = 133, left == right :false
Long left = 134, Long right = 134, left == right :false
Long left = 135, Long right = 135, left == right :false
...
Long left = 195, Long right = 195, left == right :false
Long left = 196, Long right = 196, left == right :false
Long left = 197, Long right = 197, left == right :false
Long left = 198, Long right = 198, left == right :false
Long left = 199, Long right = 199, left == right :false
通过这个超长的输出结果,你会发现,存在一个区间[-128, 127]
,在这个区间里通过 ==
这种方式返回的是true
,其他返回的都是false
。
总结
其实,通过源码分析:
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这些数的对象在内存中被缓存起来,在内存中提供重用,这些数获取的时候就会自动获取缓存中的数,而不是new出来的对象。
所以,这与自动打包拆包无关。
再所以…,判读Long对象是否相等的时候建议不要采用 ==
的形式,程序中无法绝对的判断参数值是否会在这个区间内,如果不在,那就出现让你摸不着头脑的问题。