@EqualsAndHashCode
- 此注解会生成equals(Object other) 和 hashCode()方法。
- 它默认使用非静态,非瞬态的属性
- 可通过参数exclude排除一些属性
- 可通过参数of指定仅使用哪些属性
- 它默认仅使用该类中定义的属性且不调用父类的方法
当启动@EqualsAndHashCode时,默认不调用父类的equals方法,当做类型相等判断时,会遇到麻烦,例如:
@Data
public class People {
private Integer id;
}
@Data
public class User extends People {
private String name;
private Integer age;
}
public static void main(String[] args) {
User user1 = new User();
user1.setName("jiangxp");
user1.setAge(18);
user1.setId(1);
User user2 = new User();
user2.setName("jiangxp");
user2.setAge(18);
user2.setId(2);
System.out.println(user1.equals(user2));
}
输出结果:true
注意:两条user数据,ID完全不一样,结果明显是错的,没有做id的equals判断
需要将@EqualsAndHashCode修改为@EqualsAndHashCode(callSuper = true)才能得到正确结果.
反编译修改后的User.class,发现有些许变化
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof User)) {
return false;
} else {
User other = (User)o;
if (!other.canEqual(this)) {
return false;
} else if (!super.equals(o)) { // (1)此处变化,调用了父类的equals,原:无此段逻辑
return false;
} else {
Object this$name = this.getName();
Object other$name = other.getName();
if (this$name == null) {
if (other$name != null) {
return false;
}
} else if (!this$name.equals(other$name)) {
return false;
}
Object this$age = this.getAge();
Object other$age = other.getAge();
if (this$age == null) {
if (other$age != null) {
return false;
}
} else if (!this$age.equals(other$age)) {
return false;
}
return true;
}
}
}
public int hashCode() {
int PRIME = true;
int result = super.hashCode(); //(2)此处变化,调用了父类的hashCode(); 原:int result = 1;
Object $name = this.getName();
result = result * 59 + ($name == null ? 43 : $name.hashCode());
Object $age = this.getAge();
result = result * 59 + ($age == null ? 43 : $age.hashCode());
return result;
}
总结:(1)和(2)解释了@EqualsAndHashCode(callSuper = true)的作用.