【问题标题】:Integer's specific (Java Core) [duplicate]整数的特定(Java核心)[重复]
【发布时间】:2013-10-09 06:15:13
【问题描述】:

我在面试时遇到了这个问题:

public Integer v1 = 127;
public Integer v2 = 127;
public Integer v3 = 513;
public Integer v4 = 513;

public void operatorEquals(){
    if (v1==v2)
        System.out.println("v1 == v2");
    else throw new RuntimeException("v1 != v2");
    if (v3==v4)
        System.out.println("v3 == v4");
    else throw new RuntimeException("v3 != v4");
}

**Result**: java.lang.RuntimeException: **v3 != v4**

你能解释一下:为什么?我没有建议。

【问题讨论】:

    标签: java


    【解决方案1】:

    这是自动装箱时为 Java 定义的行为。检查相关的Java Language Specification section。也阅读那里的讨论部分。以下段落摘自规范:

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

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

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

    对于整数,那些介于 -128 和 127(含)之间的自动装箱 Integer 对象将在检查 == 时返回 true。据说这些整数被缓存在一个常量池中。 但是如果你只是做new Integer(int),创建的对象总是不同的。

    【讨论】:

      【解决方案2】:

      Java Integer 对象被缓存到 127,但不超过。

      这样做的效果与String interning 的工作方式非常相似,因此所有值在[-128;127] 范围内的Integer 对象也是相同的实例 -- 返回引用相等检查也是如此,(例如==),不仅使用.equals()

      来自 Arnaud Denoyelle 的编辑

      来自 Integer.java

      public static Integer valueOf(int i) {
          assert IntegerCache.high >= 127;
          if (i >= IntegerCache.low && i <= IntegerCache.high)
              return IntegerCache.cache[i + (-IntegerCache.low)];
          return new Integer(i);
      }
      

      【讨论】:

      • 我不会那么叹气。
      • 你能解释得更详细些吗...?
      • 我编辑显示Integer#valueOf()的代码。如您所见,在 IntegerCache.low (-128) 和 IntegerCache.high (+127) 之间,您实际上并没有创建新的 Integer。
      • @user2171669 也许你也看看这里解释的字符串实习javatechniques.com/blog/string-equality-and-interning
      • @ArnaudDenoyelle 谢谢,虽然我必须说在自己编辑问题时被编辑感觉有点奇怪
      猜你喜欢
      • 2011-10-31
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多