我在采访中得到了这个问题:
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**
你能解释一下:为什么?我没有任何建议。
答案 0 :(得分:10)
Java Integer
对象被缓存到127,但不高于。
此效果与String interning的工作方式非常相似,因此值范围为[-128; 127]的所有Integer
个对象都是相同的实例也是 - 通过引用相等性检查返回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);
}
答案 1 :(得分:4)
这是Autocoxing时Java的定义行为。检查相关的Java Language Specification section。另请阅读讨论部分。以下段落取自规范:
如果装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的整数或短数,则让r1和r2为p的任意两次拳击转换的结果。始终是r1 == r2。
的情况理想情况下,装箱给定的原始值p总会产生一个 相同的参考。在实践中,这可能是不可行的 现有的实施技术。上述规则是务实的 妥协。上面的最后一个条款要求某些共同的价值 总是被装入无法区分的物体。实施可能 懒惰或急切地缓存这些。对于其他值,这个配方 不允许对盒装价值的身份做出任何假设 程序员的一部分。这将允许(但不要求)共享 部分或全部参考文献。
这确保了在大多数情况下,行为将是 期望的,特别是没有施加过度的性能损失 在小型设备上。对于内存限制较少的实现可能 例如,缓存所有char和short值,以及int和long 值范围为-32K至+ 32K。
对于整数,介于-128和127(含)之间的自动装箱的Integer对象将为check ==返回true。据说这些整数被缓存并保持在一个恒定的池中。
但是,如果您只是new Integer(int)
,创建的对象将始终不同。