Java 比较盒装 Long 值 127 和 128
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20541636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing boxed Long values 127 and 128
提问by Viraj Dhamal
I want to compare two Longobjects values using if
conditions. When these values are less than 128, the if
condition works properly, but when they are greater than or equal to 128, comparison fails.
我想使用条件比较两个Long对象的值if
。当这些值小于 128 时,if
条件正常工作,但当它们大于或等于 128 时,比较失败。
Example:
例子:
Long num1 = 127;
Long num2 = 127;
if (num1 == num2) {
// Works ok
}
Comparison on the code above works properly, but fails in the code below:
上面代码的比较工作正常,但在下面的代码中失败:
Long num1 = 128;
Long num2 = 128;
if (num1 == num2) {
// Does NOT work
}
Why is there a problem in comparing Longvariables with values greater than 127? If the variables data types are changed to long primitives, then the comparisons work for all cases.
为什么将Long变量与大于 127 的值进行比较会出现问题?如果变量数据类型更改为long 原语,则比较适用于所有情况。
采纳答案by everton
TL;DR
TL; 博士
Java caches boxed Integer instances from -128
to 127
. Since you are using ==
to compare objects referencesinstead of values, only cached objects will match. Either work with long
unboxed primitive values or use .equals()
to compare your Long
objects.
Java 缓存盒装 Integer 实例从-128
到127
。由于您使用的==
是比较对象引用而不是值,因此只有缓存的对象才会匹配。使用未long
装箱的原始值或用于.equals()
比较您的Long
对象。
Long (pun intended) version
长(双关语)版本
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.
为什么在比较 Long 变量的值大于 127 时会出现问题?如果上述变量的数据类型是原始(long),则代码适用于所有值。
Java caches Integer objects instances from the range -128 to 127. That said:
Java 缓存范围为 -128 到 127 的 Integer 对象实例。那说:
- If you set to N Long variables the value
127
(cached), the same object instance will be pointed by all references. (N variables, 1 instance) - If you set to N Long variables the value
128
(not cached), you will have an object instance pointed by every reference. (N variables, N instances)
- 如果将值
127
(缓存)设置为 N Long 变量,则所有引用都将指向同一个对象实例。(N 个变量,1 个实例) - 如果将值设置为 N Long 变量
128
(未缓存),则每个引用都会指向一个对象实例。(N 个变量,N 个实例)
That's why this:
这就是为什么:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
Outputs this:
输出这个:
true
false
真
假
For the 127Lvalue, since both references (val1 and val2) point to the same object instance in memory (cached), it returns true
.
对于127L值,由于两个引用(val1 和 val2)都指向内存(缓存)中的同一个对象实例,因此它返回true
.
On the other hand, for the 128value, 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.
在另一方面,对于128值,由于没有在存储器中缓存的实例为它被用于盒装值的任何新的分配创建一个新的,从而导致在两个不同的实例(由VAL3和VAL4指出)以及返回false
对他们之间的比较。
That happens solely because you are comparing two Long
object references, not long
primitive values, with the ==
operator. If it wasn't for this Cache mechanism, these comparisons would alwaysfail, so the real problem here is comparing boxed values with ==
operator.
发生这种情况仅仅是因为您将两个Long
对象引用而不是long
原始值与==
运算符进行比较。如果不是这种 Cache 机制,这些比较总是会失败,所以这里真正的问题是将装箱的值与==
运算符进行比较。
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:
将这些变量更改为原始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
(Proper null checking is necessary, even for castings)
(正确的空检查是必要的,即使是铸件)
IMO, it's always a good idea to stick with .equals()methods when dealing with Object comparisons.
IMO,在处理对象比较时坚持使用.equals()方法总是一个好主意。
Reference links:
参考链接:
回答by Nishan
num1
and num2
are Long objects. You should be using equals()
to compare them. ==
comparison might work sometimes because of the way JVM boxes primitives, but don't depend on it.
num1
并且num2
是 Long 对象。你应该equals()
用来比较它们。 ==
由于 JVM 装箱原语的方式,比较有时可能会起作用,但不要依赖它。
if (num1.equals(num1))
{
//code
}
回答by LionC
Comparing non-primitives (aka Objects) in Java with ==
compares their reference instead of their values. Long
is a class and thus Long
values are Objects.
比较 Java 中的非基元(又名对象)与==
比较它们的引用而不是它们的值。Long
是一个类,因此Long
值是对象。
The problem is that the Java Developers wanted people to use Long
like they used long
to provide compatibility, which led to the concept of autoboxing, which is essentially the feature, that long
-values will be changed to Long
-Objects and vice versa as needed. The behaviour of autoboxing is not exactly predictable all the time though, as it is not completely specified.
问题是 Java 开发人员希望人们Long
像以前一样使用long
以提供兼容性,这导致了自动装箱的概念,它本质上是一个特性,即-valueslong
将根据需要更改为Long
-Objects,反之亦然。然而,自动装箱的行为并不是一直完全可以预测的,因为它没有完全指定。
So to be safe and to have predictable results always use .equals()
to compare objects and do not rely on autoboxing in this case:
因此,为了安全起见并获得可预测的结果,始终使用.equals()
比较对象,在这种情况下不要依赖自动装箱:
Long num1 = 127, num2 = 127;
if(num1.equals(num2)) { iWillBeExecutedAlways(); }
回答by Jay
Java caches the primitive values from -128 to 127. When we compare two Longobjects java internally type cast it to primitive value and compare it. But above 127 the Long object will not get type caste. Java caches the output by .valueOf()method.
Java 缓存从-128 到 127的原始值。当我们比较两个Long对象时,java 在内部将其类型转换为原始值并进行比较。但高于 127 时,Long 对象将不会获得类型等级。Java 通过.valueOf()方法缓存输出。
This caching works for Byte, Short, Long from -128 to 127. For Integer caching works From -128 to java.lang.Integer.IntegerCache.high or 127, whichever is bigger.(We can set top level value upto which Integer values should get cached by using java.lang.Integer.IntegerCache.high).
此缓存适用于 Byte、Short、Long 从 -128 到 127。对于 Integer 缓存适用于从 -128 到 java.lang.Integer.IntegerCache.high 或 127,以较大者为准。(我们可以将顶级值设置为 Integer 值应该使用 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 and Double objects never gets cached.
Float 和 Double 对象永远不会被缓存。
Character will get cache from 0 to 127
字符将获得从 0 到 127 的缓存
You are comparing two objects. so ==operator will check equality of object references. There are following ways to do it.
您正在比较两个对象。所以==运算符将检查对象引用的相等性。有以下方法可以做到。
1) type cast both objects into primitive values and compare
1) 将两个对象都类型转换为原始值并进行比较
(long)val3 == (long)val4
2) read value of object and compare
2)读取对象的值并进行比较
val3.longValue() == val4.longValue()
3) Use equals() method on object comparison.
3) 在对象比较上使用 equals() 方法。
val3.equals(val4);