java - 为什么通过引用比较整数 (==) 有效?

标签 java comparison operators equality

在 Herbert Schildt 的“Java:完整引用,第 9 版”中,有一个让我有点困惑的例子。它的关键点我无法理解可以概括为以下代码:

class Test {
    public static void main (String args[]) {               
        Integer i1 = 6;
        Integer i2 = 6;

        Integer i3 = 6;
        Integer i4 = (args.length + 1) * 6;

        if (i1 == i2) System.out.println("WTF");
        if (i3 == i4) System.out.println("Super WTF!!!");
    }
}

令我惊讶的是,使用JDK 8 update 40 编译和执行此类代码的结果如下:

WTF
Super WTF!!!

我看到的所有 Java 书籍、手册和其他信息资源都指出,相等运算符 (==) 在用于比较对象时,只是匹配它们的引用值。因此,如果两个对象变量引用不同的实例,则 == 运算符将返回 false,即使这些对象的内部内容相同。这与上面示例所表达的行为完全不同。

在检查类似问题时,我发现了一个 somewhat related one ,这是关于使用 == 比较 String 对象。在那里,提到了 Java 的一个有趣的特性,称为实习。显然,所有字符串文字和编译时字符串常量都被 JVM 某种程度上“缓存”了,因此,例如,使用相同字符串文字初始化的多个 String 引用实际上指向同一个对象。

但这里我们处理数值和 Integer 对象。此外,其中一个变量 i4 是使用提供给程序的多个命令行参数进行初始化的,这绝对是一个运行时信息。然而,== 仍然发现它等于 i3

那么,鉴于以上所有内容,究竟应该如何在 Java 中使用相等运算符?在比较对象时是否会检查对象的内容?

谢谢!

最佳答案

Integer 对象被缓存,如 Integer#valueOf(int) 的 Javadocs 所述:

This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.

语句 Integer i4 = (args.length + 1) * 6; 调用返回缓存实例的 Integer#valueOf(int)。另一方面,如果您使用 Integer i4 = new Integer((args.length + 1) * 6);,引用相等性将返回 false。

关于java - 为什么通过引用比较整数 (==) 有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28925657/

相关文章:

sql - 如何比较2个表,删除旧记录并添加新记录sql

c++ - 函数应该返回引用还是对象?

c++ - C++ 中的移位运算符

java - 类转换异常 : LinearLayout cannot be cast to (java class)

java - Java中的实例方法调用

java - 比较映射忽略给定字段

java - 比较 Java 中的字符

java - Http Servlet 请求在读取一次后会丢失 POST 正文中的参数

c# - 在 LINQ to Objects 中比较字节数组

c - 两个不同事物之间比较的语法