? 在开发过程中,Lombok为我们提供了非常便捷的开发。使用注解,就能帮助我们生成get set 方法,使代码看起来更加优雅。但是@Data注解在有些情况下会有坑, 使用过程中慎用。
@Data
public class Person1 {
private String idCard;
private String sex;
}
@Data
@AllArgsConstructor
public class Student extends Person1 {
private String school;
}
上面是两个常见的类,Student继承Person1.我们看下Student生成的class文件
//equals()方法
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Student)) {
return false;
} else {
Student other = (Student)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$school = this.getSchool();
Object other$school = other.getSchool();
if (this$school == null) {
if (other$school != null) {
return false;
}
} else if (!this$school.equals(other$school)) {
return false;
}
return true;
}
}
}
//hashCode 方法
public int hashCode() {
int PRIME = true;
int result = 1;
Object $school = this.getSchool();
int result = result * 59 + ($school == null ? 43 : $school.hashCode());
return result;
}
通过观察发现Student类重写了equals和hashCode方法。但是重写的这些方法里面只有本来的字段信息,没有父类的字段信息。
public class DateTest {
public static void main(String[] args) {
Student student1 = new Student("2");
student1.setIdCard("2212");
student1.setSex("1");
Student student2 = new Student("2");
student2.setIdCard("3333");
student2.setSex("2");
System.out.println(student1 == student2);
System.out.println(student1.equals(student2));
Map<Student,String> dataTestStringMap = new HashMap<>();
dataTestStringMap.put(student1,student2.getSchool());
dataTestStringMap.put(student2,student2.getSchool());
System.out.println(dataTestStringMap.size());
System.out.println(student1.hashCode());
System.out.println(student2.hashCode());
}
}
执行结果
false
true
1
109
109
你会发现 student1 和 student2 是两个对象,但是他们的hashCode 是相同的,并且equals方法结果是true。当我们使用hashCode和equals方法的时候,就会出现问题。
方案一: 在student类上加上@EqualsAndHashCode(callSuper = true) 注解,重写父类的hashCode()和equals()
方案二: 按需加setter和getter
@Setter
@Getter
@AllArgsConstructor
public class Student extends Person1 {
private String school;
}
结果我这里就不进行验证了,读者感兴趣的,请自行验证。
文档链接: https://projectlombok.org/features/Data
有兴趣的可以,阅读一下。
? Lombok 是一个很优秀的Java库,简单的几个注解,可以干掉一大片的模版代码。当我们使用的时候,要知其然,也要知其所以然,这样才能避免不必要的坑。