Java中的整数比较

abe*_*nky 4 java boxing equality

在Java中整数比较是棘手的,因为intInteger表现不同.我得到那个部分.

但是,正如此示例程序所示,(Integer)400 (第4行)的行为与(Integer)5 (第3行)不同.为什么是这样??

import java.util.*;
import java.lang.*;
import java.io.*;

class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        System.out.format("1. 5              == 5            : %b\n", 5 == 5);
        System.out.format("2. (int)5         == (int)5       : %b\n", (int)5 == (int)5);
        System.out.format("3. (Integer)5     == (Integer)5   : %b\n", (Integer)5 == (Integer)5);
        System.out.format("4. (Integer)400   == (Integer)400 : %b\n", (Integer)400 == (Integer)400);
        System.out.format("5. new Integer(5) == (Integer)5   : %b\n", new Integer(5) == (Integer)5);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果

1. 5              == 5            : true  // Expected
2. (int)5         == (int)5       : true  // Expected
3. (Integer)5     == (Integer)5   : true  // Expected
4. (Integer)400   == (Integer)400 : false // WHAT?
5. new Integer(5) == (Integer)5   : false // Odd, but expected
Run Code Online (Sandbox Code Playgroud)

Dar*_*ila 6

因为在自动装箱中,文字Integer被评估如下:

(Integer)400 --- Integer.valueOf(400)
Run Code Online (Sandbox Code Playgroud)

valueOf is implemented such that certain numbers are "pooled", and it returns the same instance for values smaller than 128.

并且由于(Integer)5小于128,它将被汇集并且(Integer)400不会被汇集.

因此:

3. (Integer)5     == (Integer)5   : true  // Expected -- since 5 is pooled (i.e same reference)
Run Code Online (Sandbox Code Playgroud)

4. Integer(400)   == (Integer)400 : false // WHAT? -- since 400 is not pooled (i.e different reference)
Run Code Online (Sandbox Code Playgroud)


Som*_*Guy 2

来自JLS

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

理想情况下,装箱给定的原始值 p 总是会产生相同的引用。实际上,使用现有的实现技术这可能不可行。上述规则是务实的妥协。上面的最后一个子句要求始终将某些公共值装箱到无法区分的对象中。实现可以延迟或急切地缓存它们。对于其他值,此公式不允许程序员对装箱值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。

这确保了在大多数常见情况下,该行为将是所需的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存所有 char 和 Short 值,以及 -32K 到 +32K 范围内的 int 和 long 值。