5

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

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**

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

4

2 回答 2

10

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

这样做的效果与String 实习的工作方式非常相似,因此所有Integer值在 [-128;127] 范围内的对象也是相同的实例——通过引用相等检查也返回 true,(例如==),不仅使用.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);
}
于 2013-10-02T18:28:23.297 回答
4

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

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

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

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

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

于 2013-10-02T18:35:24.653 回答