1)测试准备(父类People,子类User)
@Data
//不能在此加@EqualsAndHashCode(callSuper = true),会出现报错
//Generating equals/hashCode with a supercall to java.lang.Object is pointless.
//翻译:生成对该对象的equals和hashcode方法是毫无意义的,最后分析完原理在回答这个错误的原因
public class People {
private Integer id;
}
@Data
//默认注解的callSuper=false
@EqualsAndHashCode(callSuper = true)
public class User extends People{
private String name;
private String phone;
}
2)测试类
@DisplayName("测试EqualsAndHashCode注解")
@Test
void testEqualsAndHashCode(){
User user = new User();
user.setName("1");
user.setPhone("1");
user.setId(1);
User user1 = new User();
user1.setId(2);
user1.setPhone("1");
user1.setName("1");
System.out.println(user.equals(user1));
}
结果
User类不加@EqualsAndHashCode(callSuper = true)
,输出true,
加上之后输出false
3)结果分析
@Data相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode
这5个注解的合集,所以在加了@Data注解之后,默认就将callSuper置为false了,而且在此类中存在equals(Object other)和hashCode()方法,且不会使用父类的属性,这就导致了可能的问题。避免此问题就需要增加@EqualsAndHashCode(callSuper = true)
,使用父类的属性
4)源码如下
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface EqualsAndHashCode {
String[] exclude() default {};
String[] of() default {};
//验证了callSuper的默认赋值
boolean callSuper() default false;
boolean doNotUseGetters() default false;
EqualsAndHashCode.CacheStrategy cacheStrategy() default EqualsAndHashCode.CacheStrategy.NEVER;
EqualsAndHashCode.AnyAnnotation[] onParam() default {};
boolean onlyExplicitlyIncluded() default false;
......
}
5)回顾开始的报错
@EqualsAndHashCode
注解是生成equals和hashCode方法,如果callSuper为false,则不会涉及父类的属性,而callSuper为true时,表示对父类的属性也要生成equals和hashCode方法
,而Person没有父类,所以生成不了父类的equals方法,这时候去看报错就很合理了