在 java 中,== 用于比较两个变量的内存地址是否相同,而 equals 用于比较两个对象的内容是否相等。对于基本数据类型,== 直接比较数值;对于引用类型,== 比较的是它们在堆内存中的引用地址。string 类重写了 equals 方法,因此可以比较字符串内容,而 integer、double 等包装类也重写了 equals 以比较数值大小。

基本数据类型与引用类型的 == 比较行为
当使用 == 比较基本数据类型(如 int, double)时,它直接比较存储的数值是否相等。当比较引用类型(如 String, Integer)时,== 比较的是两个变量指向的内存地址是否一致。如果两个变量指向同一个对象实例,则返回 true;否则返回 false。这是理解 Java 对象比较的基础。

public class Main {
public static void main(String[] args) {
// 基本类型比较
int a = 10;
int b = 10;
System.out.println(a == b); // true, 值相等
// 引用类型比较
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false, 不同的内存地址
String s3 = "hello";
String s4 = "hello";
System.out.println(s3 == s4); // true, 字符串常量池复用
}
}
equals 方法的默认行为与重写机制
Object 类中的 equals 方法默认实现等同于 ==,即比较内存地址。然而,许多标准库类(如 String, Integer, Date)重写了 equals 方法,使其能够比较对象的实际内容。开发者在自定义类时,如果需要基于内容进行比较,也必须重写 equals 方法,并遵循对称性、传递性和一致性契约。

import java.util.Objects;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Alice", 30);
Person p2 = new Person("Alice", 30);
System.out.println(p1.equals(p2)); // true, 内容相等
System.out.println(p1 == p2); // false, 地址不同
}
}
Integer 缓存对 == 比较的影响
在使用 Integer 包装类时,== 的行为受 JVM 整数缓存机制影响。JVM 会缓存 -128 到 127 之间的 Integer 对象。当创建该范围内的整数时,若值相同,可能返回同一缓存对象,导致 == 为 true。超出此范围或显式 new 创建的对象,== 将比较地址,通常为 false。这解释了为何某些情况下 Integer 的 == 比较看似符合直觉,实则隐藏陷阱。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











