Java整数自动自动装箱

时间:2013-09-17 13:15:54

标签: java integer autoboxing

我在Java(JDK 1.7)中偶然发现了这个:

    Integer a = 100;
    Integer b = 100;
    Integer c = 1000;
    Integer d = 1000;

    System.out.println(a == b); //true
    System.out.println(c == d); //false
    System.out.println(new Integer(100) == new Integer(100)); //false
    System.out.println(new Integer(1000) == new Integer(1000)); //false

输出是: 真正 假 假 假

为什么== b评估为真?这是什么原因?这类似于String内化吗?

3 个答案:

答案 0 :(得分:6)

  

这类似于String内化吗?

是 - 基本上所有可以放入一个字节(-128到+127)的整数都是实体,因此共享相同的底层对象。较大的不是,因此可能不共享相同的底层对象(这在JLS 5.1.7中有所介绍) - 尽管请注意,规范中没有任何内容可以防止更大的整数共享相同的内容如果有人选择以这种方式实现VM,那么就是基础对象。

我认为理由是这个范围内的“较小”整数比较大的整数使用得多,因此使用相同的底层对象是值得的,以减少潜在的内存占用。

new Integer(100) == new Integer(100)示例中,情况并非如此,因为您明确创建了新的整数对象,类似于new String("hi") == new String("hi")计算为false的方式。

重新迭代 - 在所有真实场景中比较这样的整数时,应该使用.equals()(或者最好仍然使用原始整数==),除非有使用对象类型的好例子。 )

答案 1 :(得分:1)

这是因为所有小整数都被缓存(就像String内化一样),因此当你对它们进行封装时会获得相同的实例。

来自the specification

  

如果框中的值p为true,false,则为字节或字符   范围\ u0000到\ u007f,或介于-128和127之间的int或短数字   (包括),然后让r1和r2成为任意两个拳击的结果   转换p。始终是r1 == r2。

的情况

附加说明启示了所做出的妥协:

  

理想情况下,装箱给定的原始值p总会产生一个   相同的参考。在实践中,这可能是不可行的   现有的实施技术。上述规则是务实的   妥协。上面的最后一个条款要求某些共同的价值   总是被装入无法区分的物体。实施可能   懒惰或急切地缓存这些。对于其他值,这个配方   不允许对盒装价值的身份做出任何假设   程序员的一部分。这将允许(但不要求)共享   部分或全部参考文献。

     

这确保了在大多数情况下,行为将是   期望的,特别是没有施加过度的性能损失   在小型设备上。对于内存限制较少的实现可能   例如,缓存所有char和short值,以及int和long   值范围为-32K至+ 32K。

答案 2 :(得分:1)

从-128到127的值被缓存

java.lang.Integer有一个内部静态类,可以在-128到127之间缓存所有Integer对象