java - Java 中整数比较结果各不相同

标签 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 的结果会这样因不同的值而异?

最佳答案

这个问题的答案就在Autoboxing的理解中。由Java编程语言指定。

a == b 的结果会发生变化,因为 -128 到 127 之间的任何整数都会被 Integer缓存。当创建此范围内的 int 时,将从 IntegerCache 中检索它,而不是创建新的 Integer 对象。

这是一个错误吗? 当然不是!

Java 类 Integer 也称为 wrapper 类,因为它提供了一个包装 int 基本数据类型的对象。在 Java 中,比较两个值对象并不简单。我们应该重写 Object.equal 方法(以及 Object.hashCode)并使用它来确定两个对象何时相等。在本例中,我们使用 == 运算符来比较两个物理对象地址。 Java需要new运算符来创建对象,这些对象将全部存储在JVM的堆上。局部变量存储在 JVM 的堆栈中,但它们保存对对象的引用,而不是对象本身。

在第一种情况下,当我们检查是否a == b时,我们实际上是在检查两个引用是否指向同一位置。答案是不!

但是当 a 和 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);
}

我们通过这个 Integer.valueOf 方法使用 Autoboxing Java 函数来比较 a == b。为了优化资源使用,Integer 类维护 Integer 实例的缓存。这样,所有值在 -128 到 IntegerCache.high(可配置)之间的新 Integer 请求都将返回分配一次的相同对象。因此,当我们询问是否 a == b 时,我们会得到 true,因为在幕后,a 和 b 指向相同的内存位置

现在出现了另一个问题: 这种方法是否涉及实例共享问题?幸运的是,答案是,因为 Integer 被定义为不可变对象(immutable对象),这意味着如果你想修改它,你必须获得一个新实例......令人兴奋,不是吗?

希希尔

关于java - Java 中整数比较结果各不相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22172615/

相关文章:

java apache poi - xwpfparagraph 到字符串转换

java - 使用反射加载类时避免 ClassNotFoundException

java - 写时复制集合如何提供线程安全?

java - Java 中无需 HTML 代码的 REST 实现

java - compare consistent with equals 是什么意思?如果我的类(class)不遵循这个原则,可能会发生什么?

java - 在 Java 中将 String 转换为 Long 的正确方法

Python:如何在两个单独的数组之间找到两个相等/最接近的值?

php - 有什么软件可以做文件(PHP源码)对比

java - 为什么我在这段代码中得到空指针异常?

Java 8 Lambda 自动装箱Reduce 方法