我是一名新手Java程序员,遇到了一个非常奇怪的场景,如下所示。
public static void main(String[] args) {
Integer a = 500;
Integer b = 500;
// Comparing the values.
a <= b; // true
a >= b; // true
a == b; // false
// Reassigning the values
a = 50;
b = 50;
// Again comparing the values.
a <= b; // true
a >= b; // true
a == b; // true
}
我的问题是为什么a == b
的结果会因价值的变化而变化?
答案 0 :(得分:1)
这个问题的答案在于对Java编程语言指定的Autoboxing的理解。
a == b
的结果发生变化,因为Integer
类的-128到127之间的任何整数都是缓存。当创建此范围内的int
时,将从IntegerCache
检索它,而不是创建新的Integer对象。
这是一个错误吗? 当然不是!
Java类Integer也称为 wrapper 类,因为它提供了一个包装int
原始数据类型的对象。在Java中,比较两个值对象并不是直截了当的。我们应该覆盖Object.equal
方法(以及Object.hashCode
)并使用它来确定两个对象何时相等。在这种情况下,使用==
运算符,我们将比较两个物理对象地址。 Java需要new运算符来创建对象,这些对象都将存储在JVM的Heap中。局部变量存储在JVM的堆栈中,但它们包含对象的引用,而不是对象本身。
在第一种情况下,当我们检查a == b
时,我们实际上是在检查两个引用是否都指向同一位置。对此的回答是 NO!
但是当&amp; amp; b是50?要回答这个问题,我们应该看看下面的Integer.valueOf
方法。
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
我们通过此Autoboxing
方法使用Integer.valueOf
Java函数来比较a == b
。为了优化资源使用,Integer
类维护Integer
个实例的缓存。这样,所有具有-128和IntegerCache.high
(可配置)之间值的新Integer请求将返回一次分配的相同对象。所以,当我们询问a == b时,我们得到的结果是因为,在场景后面,a和b指向相同的内存位置。
现在又出现了另一个问题: 这种方法是否涉及实例共享问题?幸运的是,答案是没有,因为Integer被定义为不可变对象,这意味着如果你想修改它,你必须得到一个新实例...... 令人兴奋,不是吗?
Shishir
答案 1 :(得分:1)
是的。因为-127到128范围内的值将存储在缓存中。所以使用equals并比较。
答案 2 :(得分:1)
Java已将-128
的值限制为127
。
这是您将此范围内的两个true
个对象与Integer
进行比较时收到==
的原因。