01_Long比较值 类型相同值不同
问题描述:
看如下代码:
Long a = 128L;
Long b = 128L;System.out.println(a == b);
运行结果如下:

明明 a 和 b 的值一样,但是结果却为 False,为什么同样的类型,同样的值,却不相等,这是为什么呢?
原因分析
那么我们就需要查看一下源码了

源码中显示,Long 中有一个静态的内部类 LongCache,专门用于缓存 -128 至 127 之间的值,一共 256 个元素。
如果值在 [-128, 127] 之间,会放在缓存里面,而超过这个范围就要 new 一个新的对象,也就是说 == 不能判断对象是否相等。
当然,如果值是在 [-128, 127] 之间的话是可以正常比较,测不出来什么问题的。
故障解决
1. 使用 .longValue() 比较
Long a = 128L;
Long b = 128L;//System.out.println(a == b);
System.out.println(a.longValue() == b.longValue());
运行结果如下:

2. 使用 .equals() 比较
Long a = 128L;
Long b = 128L;//System.out.println(a == b);
//System.out.println(a.longValue() == b.longValue());
System.out.println(a.equals(b));
运行结果如下:

总结
Long 是 long 的包装类,而用 Long 声明的变量其实是对象。在 Java 中,== 运算符用于比较基本数据类型时,比较的是它们的值是否相等;但用于比较对象时,比较的是它们在内存中的地址是否相同。 对于 Long 类型来说,其内部存在 LongCache 这个静态内部类用于缓存 -128 至 127 之间的值,一共 256 个元素。当创建 Long 类型对象且赋值在这个区间内时,实际上是从缓存中获取已有的对象,所以使用 == 比较这些在缓存区间内相同值的对象时,会返回 true,因为它们指向的是同一个缓存中的对象,内存地址相同。
然而,一旦赋值超出了 [-128, 127] 这个范围,就会新创建一个 Long 对象,像示例中赋值为 128L 的情况,a 和 b 虽然值相同,但它们是两个不同的对象,在内存中有不同的地址,所以直接使用 == 比较就会返回 false。
- 通过使用
.longValue()方法,是将Long对象转换为基本数据类型long再进行比较,此时比较的就是具体的数值了,所以只要数值相等就能返回true。 - 通过使用
.equals()方法时,Long类重写了Object类的equals()方法,它是先通过.longValue()方法获取Long对象的基本类型long的值之后再做比较。
总之,在比较 Long 类型对象的值是否相等时,要谨慎使用 == 运算符,尽量采用.equals() 的方式来(或者是.longValue()的方式)确保比较的是实际的数值,避免因对象内存地址不同而导致比较结果不符合预期
