【问题标题】:Java Integer auto auto-boxing [duplicate]Java整数自动装箱[重复]
【发布时间】:2013-09-17 13:15:53
【问题描述】:

我在 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

输出是: 真的 错误的 错误的 假的

为什么 a==b 的计算结果为真?这是什么原因?这和字符串内化类似吗?

【问题讨论】:

    标签: java integer autoboxing


    【解决方案1】:

    这和字符串内化类似吗?

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

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

    在您的 new Integer(100) == new Integer(100) 示例中,情况并非如此,因为您正在显式创建新的整数对象,类似于 new String("hi") == new String("hi") 评估为 false 的方式。

    只是重申一下-在所有现实世界场景中比较像这样的整数时,应该使用.equals()(或者最好仍然使用原始整数==,除非有使用对象类型的好案例。)

    【讨论】:

    • 这不是一个常见的错误,但它是对数字、布尔值等使用原生 Java 类型的一个很好的理由......
    【解决方案2】:

    这是因为所有的小整数都被缓存了(比如字符串内部化),所以当你把它们装箱时你会得到相同的实例。

    来自the specification

    如果被装箱的值 p 是真、假、字节或字符 范围 \u0000 到 \u007f,或介于 -128 和 127 之间的整数或短数字 (含),则令 r1 和 r2 为任意两个装箱的结果 p的转换。 r1 == r2 总是如此。

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

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

    这可确保在最常见的情况下,行为将是 理想的,而不会造成不适当的性能损失,尤其是 在小型设备上。更少的内存限制实现可能,对于 例如,缓存所有 char 和 short 值,以及 int 和 long 值在 -32K 到 +32K 的范围内。

    【讨论】:

    • 谢谢。整数需要多小?这样做的主要原因是什么,性能和内存占用?
    【解决方案3】:

    缓存从 -128 到 127 的值

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

    【讨论】:

      猜你喜欢
      • 2011-05-02
      • 2018-06-20
      • 1970-01-01
      • 1970-01-01
      • 2012-04-28
      • 2011-01-19
      • 2014-01-21
      • 1970-01-01
      • 2016-05-18
      相关资源
      最近更新 更多