比较加框的长值127和128
我想使用if
条件比较两个Long对象值。 当这些值小于128时 , if
条件正常工作,但当它们大于或等于128时 ,比较失败。
例:
Long num1 = 127; Long num2 = 127; if (num1 == num2) { // Works ok }
上面的代码比较正常,但在下面的代码中失败:
Long num1 = 128; Long num2 = 128; if (num1 == num2) { // Does NOT work }
为什么比较Long变量和大于127的值存在问题? 如果变量数据类型更改为长基元 ,则比较适用于所有情况。
TL; DR
Java缓存从-128
到127
整数盒装实例。 由于您使用==
来比较对象引用而不是值,因此只有缓存的对象才匹配。 以太使用long
装箱原始值或使用.equals()
来比较Long
对象。
长版
为什么在比较Long变量和大于127的值时存在问题? 如果上面变量的数据类型是原始的(长),则代码适用于所有值。
Java缓存范围为-128到127的整数对象实例 。 那说:
- 如果设置为N Long变量值
127
( 缓存 ),则所有引用都将指向相同的对象实例。 (N个变量,1个实例) - 如果设置为N Long变量值
128
( 未缓存 ),则每个引用都会指向一个对象实例。 (N个变量,N个实例)
这就是为什么这个:
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
原始值)与==
运算符进行比较。 如果不是这种Cache机制,那么这些比较总是会失败,所以这里真正的问题是将盒装值与==
运算符进行比较。
将这些变量更改为原始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 ,在处理Object比较时坚持使用.equals()方法总是一个好主意。
免责声明:如果这些值中的任何一个为空(即使转换为long将抛出exception),大多数比较都将失败,因此需要额外的检查来适应这些情况。
参考链接:
num1
和num2
是Long对象。 您应该使用equals()
来比较它们。 ==
比较可能有时会起作用,因为JVM框原语的方式,但不依赖它。
if (num1.equals(num1)) { //code }
Java将原始值从-128缓存到127 。 当我们比较两个Long对象java内部类型时,将其转换为原始值并进行比较。 但是在127以上,Long对象将不会获得类型种姓。 Java通过.valueOf()方法缓存输出。
这个缓存适用于-128到127的字节,短,长。对于整数缓存工作从-128到java.lang.Integer.IntegerCache.high或127,取较大者。(我们可以将顶级值设置为整数值应该通过使用java.lang.Integer.IntegerCache.high来缓存。
For example: If we set java.lang.Integer.IntegerCache.high=500; then values from -128 to 500 will get cached and Integer a=498; Integer b=499; System.out.println(a==b) Output will be "true".
Float和Double对象永远不会被缓存。
字符将从0到127获得缓存
您正在比较两个对象。 so == operator将检查对象引用的相等性。 有以下方法可以做到这一点。
1)键入将两个对象转换为原始值并进行比较
(long)val3 == (long)val4
2)读取对象的值并进行比较
val3.longValue() == val4.longValue()
3)对对象比较使用equals()方法。
val3.equals(val4);
比较Java中的非基元(aka对象)与==
比较它们的引用而不是它们的值。 Long
是一个类,因此Long
值是Objects。
问题是Java开发人员希望人们像long
使用Long
那样使用Long
来提供兼容性,从而导致自动装箱的概念,其本质上就是这个特性, long
将根据需要更改为Long
-Objects,反之亦然。 然而,自动装箱的行为并不是完全可预测的,因为它没有完全指定。
因此,为了安全并具有可预测的结果,请始终使用.equals()
来比较对象,并且在这种情况下不依赖于自动装箱:
Long num1 = 127, num2 = 127; if(num1.equals(num2)) { iWillBeExecutedAlways(); }