原因
在Java中,`Integer` 和 `String` 是包装类和不可变类,它们分别对基本类型 `int` 和字符数组提供了类的包装。当使用 `==` 操作符对这些类型的对象进行比较时,实际上比较的是它们在内存中的引用地址,而不是它们的值。这就意味着,即使两个对象包含相同的值,它们也可能在内存中有不同的地址,因此 `==` 会返回 `false`。
举例
对于 `Integer` 类型:
Integer a = 127;
Integer b = 127;
System.out.println(a == b); // 这可能会打印 true,因为自动装箱使用了Integer缓存
Integer c = 128;
Integer d = 128;
System.out.println(c == d); // 这将会打印 false
在上面的例子中,变量 `a` 和 `b` 可能引用了相同的对象,因为Java缓存了 `-128` 到 `127` 之间的 `Integer` 对象。(这个缓存定义在 java.lang.Integer.IntegerCache 静态内部类中)而 `c` 和 `d` 是两个不同的对象,因为它们的值不在缓存范围内,所以它们在内存中有不同的地址。
对于 `String` 类型:
String x = "hello";
String y = "hello";
System.out.println(x == y); // 这将打印 true,因为字符串常量池的作用
String z = new String("hello");
System.out.println(x == z); // 这将打印 false
在这个例子中,`x` 和 `y` 引用了字符串常量池中的同一个对象。但是,由于使用了 `new` 关键字,`z` 引用了一个新的 `String` 对象,即使它包含相同的字符序列也不会相等。
为了比较 `Integer` 或 `String` 对象的值,应该使用它们各自的 `equals()` 方法。`equals()` 方法被设计用来比较对象的内容是否相等。
Integer a = 128;
Integer b = 128;
System.out.println(a.equals(b)); // 这将打印 true
String x = new String("hello");
String y = "hello";
System.out.println(x.equals(y)); // 这将打印 true
总结
如果想比较两个对象是否在逻辑上相等,应该使用 `equals()` 方法。
如果你想知道两个引用是否指向内存中的同一个对象,你可以使用 `==` 操作符。在处理包装类或不可变类时,通常关心的是逻辑上的等价性,所以 `equals()` 是正确的选择。