You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

克隆对象equals返回false:深拷贝实现后数据一致仍不相等

问题根源

你遇到的问题和深拷贝本身无关,核心是你没有重写BankAccount类的equals()方法。Java中Object类默认的equals()实现是直接比较对象的内存地址(相当于==),而深拷贝出来的account2是全新对象,和account1内存地址不同,所以哪怕所有字段内容一致,equals()也会返回false。

解决方案:重写equals()和hashCode()

要让equals()比较对象内容而非地址,你需要在BankAccount类中重写equals()方法,同时按照Java规范必须同步重写hashCode()方法(否则使用HashMap、HashSet等哈希集合时会出现异常行为)。

假设你的BankAccount类包含accountNumber(账号)、balance(余额)、createDate(创建日期)这几个核心字段,以下是完整的重写示例:

import java.util.Date;

public class BankAccount implements Cloneable {
    private int accountNumber;
    private int balance;
    private Date createDate;

    // 构造器
    public BankAccount(int accountNumber, int balance) {
        this.accountNumber = accountNumber;
        this.balance = balance;
        this.createDate = new Date(); // 假设创建对象时初始化日期
    }

    // 你的clone方法(保持不变)
    @Override
    public Object clone() {
        try {
            // 浅拷贝
            BankAccount clone = (BankAccount) super.clone();
            // 深拷贝引用类型字段
            clone.createDate = (Date) createDate.clone();
            return clone;
        } catch (CloneNotSupportedException e) {
            return null;
        }
    }

    // 重写equals方法
    @Override
    public boolean equals(Object o) {
        // 1. 同一对象引用直接返回true
        if (this == o) return true;
        // 2. 类型不同或为null返回false
        if (o == null || getClass() != o.getClass()) return false;
        // 3. 强转为BankAccount类型
        BankAccount that = (BankAccount) o;
        // 4. 逐个比较所有核心字段:基本类型用==,引用类型用equals
        return accountNumber == that.accountNumber &&
                balance == that.balance &&
                createDate.equals(that.createDate);
    }

    // 重写hashCode方法
    @Override
    public int hashCode() {
        // 基于equals中用到的字段计算哈希值
        int result = accountNumber;
        result = 31 * result + balance;
        result = 31 * result + createDate.hashCode();
        return result;
    }

    // main测试方法
    public static void main(String[] args) {
        BankAccount account1 = new BankAccount(1111, 5347);
        BankAccount account2 = (BankAccount) account1.clone();

        System.out.println(account2.equals(account1)); // 现在会输出true
    }
}
关键说明
  • equals()方法中,对于引用类型字段(比如Date),必须调用其自身的equals()方法比较内容,不能用==(否则还是比较地址)。
  • hashCode()方法的计算要基于equals()中用到的所有字段,用31是因为它是质数,能减少哈希冲突。
  • 后续给BankAccount新增字段时,要同步更新equals()和hashCode()方法,避免逻辑不一致。

内容的提问来源于stack exchange,提问作者Jack0thy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:53:28