Java中的整数比较

时间:2015-04-08 12:51:22

标签: java equality boxing

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

但是,正如此example program所示,(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);
    }
}

结果

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

3 个答案:

答案 0 :(得分:6)

因为在将文字自动装箱到Integer时,评估如下:

(Integer)400 --- Integer.valueOf(400)

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)

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

答案 1 :(得分:4)

以下是JLS的引用:

  

如果装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的整数或短数,则让r1和r2为p的任意两次拳击转换的结果。始终是r1 == r2。

的情况

简而言之,Integer使用了游戏池,因此对于从-128到127的数字,您将在装箱后始终获得相同的对象,例如new Integer(120) == new Integer(120)将评估为true,但{ {1}}将评估为new Integer(130) == new Integer(130)

答案 2 :(得分:2)

来自JLS

  

如果装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的整数或短数,则让r1和r2为p的任意两次拳击转换的结果。始终是r1 == r2。

的情况      

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

     

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