如何重写含30+属性类的equals方法,避免逐一列举属性?
嘿,我完全懂这种痛苦——30多个属性一个个写Objects.equals(),不仅手酸还容易漏写,后期加属性也容易忘更新equals方法。给你几个实用的解决方案,按推荐程度排序:
1. 用Lombok(最省心的方案)
这绝对是首选,只需要在你的类上加上@EqualsAndHashCode注解,Lombok会在编译时自动帮你生成覆盖所有非静态、非transient属性的equals和hashCode方法,完全不用自己写一行代码。
示例代码:
import lombok.EqualsAndHashCode; @EqualsAndHashCode public class Address { private String attr1; private int attr2; // ... 剩下30多个属性 }
如果需要自定义规则,还可以通过注解参数调整:
exclude = {"attrX"}:排除指定属性不参与比较callSuper = true:将父类的字段也纳入比较范围
2. 用Apache Commons Lang的EqualsBuilder
如果你不想引入Lombok,Apache Commons Lang库的EqualsBuilder提供了反射式的比较方法,一行代码就能搞定:
import org.apache.commons.lang3.builder.EqualsBuilder; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Address address = (Address) o; return EqualsBuilder.reflectionEquals(this, address); }
同样支持自定义排除字段:
// 排除attr3和attr5不参与比较 return EqualsBuilder.reflectionEquals(this, address, "attr3", "attr5");
也可以通过reflectionEquals(this, address, false)来关闭默认的transient字段忽略规则。
3. 手动实现反射遍历(适合不想加依赖的场景)
如果不想引入任何第三方库,也可以自己写反射代码来遍历字段。不过要注意处理字段权限、静态/transient字段过滤,以及异常情况:
import java.lang.reflect.Field; import java.util.Objects; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Address other = (Address) o; Field[] fields = getClass().getDeclaredFields(); for (Field field : fields) { // 跳过静态和transient字段 if (java.lang.reflect.Modifier.isStatic(field.getModifiers()) || java.lang.reflect.Modifier.isTransient(field.getModifiers())) { continue; } try { field.setAccessible(true); Object thisValue = field.get(this); Object otherValue = field.get(other); if (!Objects.equals(thisValue, otherValue)) { return false; } } catch (IllegalAccessException e) { throw new RuntimeException("Failed to compare fields in equals method", e); } } return true; }
这种方式会自动适配类的字段变化,不用手动更新equals方法,但反射性能略低于手动编写的代码,适合非高频调用的场景。
重要提醒
不管用哪种方案,都要保证hashCode方法和equals方法逻辑一致(比如Lombok会自动生成匹配的hashCode,EqualsBuilder也有reflectionHashCode方法),否则会导致HashMap、HashSet等集合类行为异常。
内容的提问来源于stack exchange,提问作者Mohamed Taboubi
相关产品推荐
相关产品推荐

