整数比较结果在Java中变化

时间:2014-03-04 12:58:01

标签: java comparison autoboxing

我是一名新手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的结果会因价值的变化而变化?

3 个答案:

答案 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进行比较时收到==的原因。