为什么 == 与 Integer.valueOf(String) 的比较会给出 127 和 128 的不同结果?

2022-08-31 06:34:31

我不知道为什么这些代码行返回不同的值:

System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));

输出为:

true
false
true

为什么第一个返回,第二个返回?和 之间有什么我不知道的不同吗?(我当然知道<。truefalse127128127128

另外,为什么第三个会返回?true

我已经阅读了这个问题的答案,但我仍然不明白它如何返回,以及为什么第二行中的代码返回。truefalse


答案 1

这里有一个惊人的区别。

valueOf返回一个对象,该对象的值可能缓存在 -128 和 127 之间。这就是为什么第一个值返回 - 它被缓存 - 第二个值返回 - 128不是缓存值,所以你得到两个单独的实例。IntegertruefalseInteger

请务必注意,您正在将引用与 进行比较,并且如果您正在比较的值大于缓存支持的值,则即使解析的值是等效的,它也不会计算为 。您必须改用。Integer#valueOftrueInteger.valueOf(128) == Integer.valueOf(128)equals()

parseInt返回一个原语。这就是为什么第三个值返回 - 被评估,当然是。inttrue128 == 128true

现在,相当多的人碰巧做出了第三个结果:true

  • 对于您正在使用的等价运算符和您拥有的数据类型(即和 ),会发生取消装箱转换。当然,你从右手边得到一个。intIntegerIntegervalueOf

  • 转换后,您将比较两个基元值。比较就像你对基元的期望一样,所以你最终会比较和。int128128


答案 2

该类具有静态缓存,该缓存存储 256 个特殊对象 - 一个用于 -128 和 127 之间的每个值。考虑到这一点,请考虑这三者之间的区别。IntegerInteger

new Integer(123);

这(显然)使一个全新的对象。Integer

Integer.parseInt("123");

这将在解析 .intString

Integer.valueOf("123");

这比其他问题更复杂。它首先解析 .然后,如果该值介于 -128 和 127 之间,它将从静态缓存中返回相应的对象。如果值超出此范围,则它将调用并传入该值,以便获取新对象。Stringnew Integer()

现在,考虑问题中的三个表达式。

Integer.valueOf("127")==Integer.valueOf("127");

这将返回 true,因为其值为 127 将从静态缓存中检索两次,并与自身进行比较。只涉及一个对象,因此返回 。IntegerIntegertrue

Integer.valueOf("128")==Integer.valueOf("128");

这将返回 ,因为 128 不在静态缓存中。因此,为平等的每一方都创建了一个新的。由于有两个不同的对象,并且对于对象,仅当两端都是完全相同的对象时才返回,因此这将是 。falseIntegerInteger==truefalse

Integer.parseInt("128")==Integer.valueOf("128");

这是将左侧的基元值 128 与右侧新创建的对象进行比较。但是,因为将 an 与 a 进行比较没有意义,Java 会在进行比较之前自动取消装箱;因此,您最终会将 an 与 .由于基元 128 等于自身,因此返回 。intIntegerintIntegerIntegerintinttrue


推荐