编程语言
首页 > 编程语言> > java – 比较已装箱的长值127和128

java – 比较已装箱的长值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的盒装整数实例.由于您使用==来比较对象引用而不是值,因此只有缓存的对象才匹配.使用长的未装箱原始值或使用.equals()来比较Long对象.

长(双关语)版本

Why there is problem in comparing Long variable with value greater than 127? If the data type of above variable is primitive (long) then code work for all values.

Java caches Integer objects instances from the range -128 to 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);

输出:

true
false

对于127L值,由于两个引用(val1和val2)都指向内存中的相同对象实例(缓存),因此返回true.

另一方面,对于128值,由于没有缓存在内存中的实例,因此为盒装值的任何新赋值创建一个新值,从而产生两个不同的实例(由val3和val4指向)并返回false他们之间的比较.

这只是因为您将两个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()方法总是一个好主意.

参考链接:

> https://today.java.net/pub/a/today/2005/03/24/autoboxing.html
> https://blogs.oracle.com/darcy/entry/boxing_and_caches_integer_valueof
> http://java.dzone.com/articles/surprising-results-autoboxing

标签:java,comparison,autoboxing
来源: https://codeday.me/bug/20190917/1809675.html