克隆对象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
相关产品推荐
相关产品推荐

