问题描述:
看如下代码:
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()
的方式)确保比较的是实际的数值,避免因对象内存地址不同而导致比较结果不符合预期