比较框中的 Long 值127和128

我想使用 if条件比较两个 很长对象值。当这些值为 少于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
}

为什么在比较 很长变量和值 大于127时会有问题?如果变量数据类型更改为 长原始人,则比较适用于所有情况。

158666 次浏览

num1num2是长对象。您应该使用 equals()来比较它们。==比较有时可能会因为 JVM 装箱原语的方式而起作用,但并不依赖于它。

if (num1.equals(num1))
{
//code
}

比较 Java 中的非原语(aka Objects)和 ==比较它们的引用而不是它们的值。Long是一个类,因此 Long值是对象。

问题是 Java 开发人员希望人们像使用 long一样使用 Long来提供兼容性,这导致了自动装箱的概念,这本质上是一个特性,long的值将被更改为 Long-Objects,反之亦然。但是,自动装箱的行为并不总是完全可预测的,因为它并没有完全指定。

因此,为了安全起见,为了得到可预测的结果,总是使用 .equals()来比较对象,在这种情况下不要依赖于自动装箱:

Long num1 = 127, num2 = 127;
if(num1.equals(num2)) { iWillBeExecutedAlways(); }

DR

Java 将装箱的 Integer 实例从 -128缓存到 127。由于使用 ==比较对象 参考文献而不是 价值观,因此只有缓存的对象才能匹配。使用 long未装箱的基元值或使用 .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 缓存范围从 -128到127 的 Integer 对象实例:

  • 如果将值 127(缓存)设置为 N Long 变量,则所有引用都将指向相同的对象实例。(N 个变量,1个实例)
  • 如果将值 128(没有缓存)设置为 N Long 变量,则每个引用都会指向一个对象实例。(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
假的

对于 127L值,因为两个引用(val1和 val2)都指向内存(缓存)中的同一个对象实例,所以它返回 true

On the other hand, for the 128 value, since there is no instance for it cached in memory, a new one is created for any new assignments for boxed values, resulting in two different instances (pointed by val3 and val4) and returning false on the comparison between them.

That happens solely because you are comparing two Long 对象引用, not long primitive values, with the == operator. If it wasn't for this Cache mechanism, these comparisons would 一直都是 fail, so the real problem here is comparing boxed values with == operator.

Changing these variables to primitive long types will prevent this from happening, but in case you need to keep your code using Long objects, you can safely make these comparisons with the following approaches:

System.out.println(val3.equals(val4));                     // true
System.out.println(val3.longValue() == val4.longValue());  // true
System.out.println((long)val3 == (long)val4);              // true

(适当的零检查是必要的,即使是铸件)

IMO, it's always a good idea to stick with 等于() methods when dealing with Object comparisons.

参考链接:

Java 缓存来自 -128到127的基元值。当我们比较两个 很长对象时,java 内部类型将其转换为原始值并进行比较。但是在127以上 Long 对象将不会得到类型种姓。Java 通过 . valueOf ()方法缓存输出。

此缓存适用于从 -128到127的 Byte,Short,Long。 对于整数缓存工程从 -128到 java.lang。整数。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的缓存

你在比较两个对象。因此,==运算符将检查对象引用的相等性。有以下几种方法可以做到这一点。

1) type cast both objects into primitive values and compare

    (long)val3 == (long)val4

2)读取对象值并进行比较

    val3.longValue() == val4.longValue()

3)在对象比较中使用 equals ()方法。

    val3.equals(val4);