Java:整数等于与==

发布于 2024-09-17 19:00:39 字数 1044 浏览 6 评论 0原文

从 Java 1.5 开始,在许多情况下您几乎可以将 Integerint 互换。

然而,我在代码中发现了一个潜在的缺陷,这让我有点惊讶。

以下代码:

Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
    mismatch = true;

当值相等时,似乎错误地设置了不匹配,尽管我无法确定在什么情况下。我在 Eclipse 中设置了一个断点,发现 Integer 值都是 137,我检查了布尔表达式,它说它是 false,但是当我跨过它时,它会将不匹配设置为 true。

将条件更改为:

if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))

解决了问题。

谁能解释一下为什么会发生这种情况?到目前为止,我只在我自己的 PC 上的本地主机上看到了该行为。在这种特殊情况下,代码成功地通过了大约 20 次比较,但在 2 次比较中失败了。该问题始终可以重现。

如果这是一个普遍的问题,它应该会在我们的其他环境(开发和测试)上导致错误,但到目前为止,在执行此代码片段的数百次测试后,没有人报告该问题。

使用 == 比较两个 Integer 值仍然不合法吗?

除了下面的所有详细答案之外,下面的 stackoverflow 链接还有很多附加信息。它实际上会回答我原来的问题,但因为我在问题中没有提到自动装箱,所以它没有出现在选定的建议中:

为什么编译器/JVM 不能让自动装箱“正常工作”?

As of Java 1.5, you can pretty much interchange Integer with int in many situations.

However, I found a potential defect in my code that surprised me a bit.

The following code:

Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
    mismatch = true;

appeared to be incorrectly setting mismatch when the values were equal, although I can't determine under what circumstances. I set a breakpoint in Eclipse and saw that the Integer values were both 137, and I inspected the boolean expression and it said it was false, but when I stepped over it, it was setting mismatch to true.

Changing the conditional to:

if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))

fixed the problem.

Can anyone shed some light on why this happened? So far, I have only seen the behavior on my localhost on my own PC. In this particular case, the code successfully made it past about 20 comparisons, but failed on 2. The problem was consistently reproducible.

If it is a prevalent problem, it should be causing errors on our other environments (dev and test), but so far, no one has reported the problem after hundreds of tests executing this code snippet.

Is it still not legitimate to use == to compare two Integer values?

In addition to all the fine answers below, the following stackoverflow link has quite a bit of additional information. It actually would have answered my original question, but because I didn't mention autoboxing in my question, it didn't show up in the selected suggestions:

Why can't the compiler/JVM just make autoboxing “just work”?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

烈酒灼喉 2024-09-24 19:00:39

JVM 正在缓存整数值。因此,与 == 的比较仅适用于 -128 和 127 之间的数字。

请参阅:#Immutable_Objects_.2F_Wrapper_Class_Caching

The JVM is caching Integer values. Hence the comparison with == only works for numbers between -128 and 127.

Refer: #Immutable_Objects_.2F_Wrapper_Class_Caching

谁许谁一生繁华 2024-09-24 19:00:39

您无法将两个 Integer 与简单的 == 进行比较,它们是对象,因此大多数时候引用不会相同。

有一个技巧,Integer 介于 -128 和 127 之间,引用将与自动装箱使用 Integer.valueOf() 缓存小整数相同。

如果装箱的值 p 是 true、false、字节、\u0000 到 \u007f 范围内的字符,或者 -128 到 127 之间的 int 或短数字,则令 r1 和 r2 为任意结果p 的两次拳击转换。 r1 == r2 的情况总是如此。


资源:

同一主题:

You can't compare two Integer with a simple == they're objects so most of the time references won't be the same.

There is a trick, with Integer between -128 and 127, references will be the same as autoboxing uses Integer.valueOf() which caches small integers.

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.


Resources :

On the same topic :

森林很绿却致人迷途 2024-09-24 19:00:39

“==”始终比较值的内存位置或对象引用。 equals 方法总是比较值。但 equals 也间接使用“==”运算符来比较值。

Integer 使用 Integer 缓存来存储从 -128 到 +127 的值。如果 == 运算符用于检查 -128 到 127 之间的任何值,则返回 true。对于除这些值之外的其他值,它返回 false 。

请参阅链接了解一些其他信息

"==" always compare the memory location or object references of the values. equals method always compare the values. But equals also indirectly uses the "==" operator to compare the values.

Integer uses Integer cache to store the values from -128 to +127. If == operator is used to check for any values between -128 to 127 then it returns true. for other than these values it returns false .

Refer the link for some additional info

千寻… 2024-09-24 19:00:39

Integer 指的是引用,也就是说,在比较引用时,您要比较的是它们是否指向同一对象,而不是值。因此,出现了您所看到的问题。它能够很好地处理普通 int 类型的原因是它对 Integer 包含的值进行拆箱。

我可以补充一点,如果您正在做您正在做的事情,为什么要以 if 语句开头呢?

mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) );

Integer refers to the reference, that is, when comparing references you're comparing if they point to the same object, not value. Hence, the issue you're seeing. The reason it works so well with plain int types is that it unboxes the value contained by the Integer.

May I add that if you're doing what you're doing, why have the if statement to begin with?

mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) );
暗恋未遂 2024-09-24 19:00:39

问题是你的两个 Integer 对象就是那个对象。它们不匹配,因为您正在比较两个对象引用,而不是其中的值。显然 .equals 被重写以提供值比较,而不是对象引用比较。

The issue is that your two Integer objects are just that, objects. They do not match because you are comparing your two object references, not the values within. Obviously .equals is overridden to provide a value comparison as opposed to an object reference comparison.

小耗子 2024-09-24 19:00:39

除了这些给出的很好的答案之外,我学到的是:

切勿将对象与 == 进行比较,除非您打算比较它们
通过他们的参考。

Besides these given great answers, What I have learned is that:

NEVER compare objects with == unless you intend to be comparing them
by their references.

雪若未夕 2024-09-24 19:00:39

为了确保使用 == 的正确性,您可以在进行 == 比较之前取消比较的 Integer 值之一,例如:

if ( firstInteger.intValue() == secondInteger ) {..

第二个将是自动拆箱(当然,您必须首先检查 null)。

As well for correctness of using == you can just unbox one of compared Integer values before doing == comparison, like:

if ( firstInteger.intValue() == secondInteger ) {..

The second will be auto unboxed (of course you have to check for nulls first).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文