侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

Java中==和equals()的区别及重写equals()的规范

2025-12-6 / 0 评论 / 4 阅读

题目

Java中==和equals()的区别及重写equals()的规范

信息

  • 类型:问答
  • 难度:⭐⭐

考点

对象比较,equals方法重写,==运算符,hashCode契约

快速回答

核心区别:

  • ==运算符:比较对象内存地址(引用相等)或基本类型值
  • equals()方法:默认比较引用,但通常被重写为比较对象内容(逻辑相等)

重写规范:

  1. 重写equals()必须同时重写hashCode()
  2. 遵循自反性、对称性、传递性、一致性
  3. 处理null和类型检查
## 解析

一、核心区别

==运算符:

  • 对基本类型(int, char等)比较
  • 对引用类型比较内存地址(是否同一对象)
  • 示例:
    String a = new String("abc");
    String b = new String("abc");
    a == b; // false(不同对象)

equals()方法:

  • Object类默认实现等同于==
  • 通常被重写实现逻辑相等(如String比较字符内容)
  • 示例:
    a.equals(b); // true(内容相同)

二、重写equals()规范

正确重写示例:

class Person {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        // 1. 自反性
        if (this == o) return true;
        // 2. 非空和类型检查
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        // 3. 比较关键字段
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        // 4. 必须重写hashCode(重要!)
        return Objects.hash(name, age);
    }
}

三、必须遵守的契约

  1. 自反性:x.equals(x) 必须为true
  2. 对称性:x.equals(y) 与 y.equals(x) 结果相同
  3. 传递性:x.equals(y)且y.equals(z) 则 x.equals(z)
  4. 一致性:多次调用结果不变(不依赖可变字段)
  5. 非空性:x.equals(null) 必须返回false

四、常见错误

  • 未重写hashCode:导致HashMap/HashSet行为异常
    // 错误示例:只重写equals不重写hashCode
    Set<Person> set = new HashSet<>();
    set.add(new Person("Tom", 20));
    set.contains(new Person("Tom", 20)); // 可能返回false
  • 违反对称性
    // 错误示例
    class A {
        boolean equals(B b) { ... } // 参数类型错误!
    }
  • 比较可变字段:对象放入集合后修改字段导致找不到

五、最佳实践

  1. 使用IDE自动生成equals/hashCode(如IntelliJ/ECJ)
  2. 优先使用Objects.equals()比较字段避免NPE
  3. 对于不可变类(如String),字段比较是安全的
  4. 数组比较用Arrays.equals()

六、扩展知识

  • hashCode契约:相等对象必须有相同hashCode,但反之不成立
  • instanceof vs getClass()
    getClass()要求严格类型匹配,instanceof支持子类(需根据设计选择)
  • Objects.equals():安全处理null的比较工具方法