TL;DR
Java 将盒装整数实例从 高速缓存到 。由于 您 使用的是比较对象引用而不是值,因此只有缓存的对象才会匹配。可以使用未装箱的基元值,也可以使用 来比较对象。-128
127
==
long
.equals()
Long
长(双关语)版本
为什么将多头变量与大于 127 的值进行比较时存在问题?如果上述变量的数据类型是基元(长整型),则代码适用于所有值。
Java 缓存范围为 -128 到 127 的 Integer 对象实例。可是:
- 如果将值(缓存)设置为 N Long 变量,则所有引用都将指向同一对象实例。(N 个变量,1 个实例)
127
- 如果将值设置为 N Long 变量(未缓存),则每个引用都将有一个对象实例。(N 个变量,N 个实例)
128
这就是为什么:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
输出此:
真
假
对于 127L 值,由于两个引用(val1 和 val2)都指向内存中的同一对象实例(缓存),因此返回 。true
另一方面,对于 128 值,由于内存中没有缓存它的实例,因此会为盒装值的任何新赋值创建一个新实例,从而产生两个不同的实例(由 val3 和 val4 指向),并在它们之间的比较中返回。false
发生这种情况仅仅是因为您正在将两个对象引用(而不是基元值)与运算符进行比较。如果不是这种缓存机制,这些比较将始终失败,因此此处的真正问题是将盒装值与运算符进行比较。Long
long
==
==
将这些变量更改为基元类型将防止这种情况发生,但是如果您需要使用对象保留代码,则可以使用以下方法安全地进行这些比较:long
Long
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(必须进行适当的空值检查,即使对于铸件也是如此)
IMO,在处理对象比较时坚持使用.equals()方法总是一个好主意。
参考链接: