lombok——@EqualsAndHashCode(callSuper=true)注解的。
。。
此注解会⽣成equals(Object other) 和 hashCode()⽅法。
它默认使⽤⾮静态,⾮瞬态的属性
可通过参数exclude排除⼀些属性
可通过参数of指定仅使⽤哪些属性
它默认仅使⽤该类中定义的属性且不调⽤⽗类的⽅法
实现equals, hashCode⽅法是在编程⽣活中再常见不过的⼀个东西了,那么⾃然@EqualsAndHashCode 这个annotation就成为了⼀个⾮常⽅便的⼯具。默认情况下,被这个annotation标注的class会⽤到除了 static,transient修饰的所有属性作为判断标准,当然和之前的annotation⼀样,可是使⽤exclude选项除掉不想要的属性。也可以通过callSuper包含⽗类的equals 和 hashCode。当然如果你的class 没有继承任何其他的class,你却写了callSuper,那么会收获⼀个编译报错。
你只要这样⽤:
Java代码
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(exclude={"id", "shape"})
public class EqualsAndHashCodeExample {
private transient int transientVar = 10;
private String name;
private double score;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
public String getName() {
return this.name;
}
@EqualsAndHashCode(callSuper=true)
public static class Square extends Shape {
private final int width, height;
public Square(int width, int height) {
this.width = width;
this.height = height;
}
}
}
@EqualsAndHashCode(callSuper = true)
该注解⽤于⼦类对象之间进⾏⽐较的时候
不加该注解的影响:⼦类对象属性值⼀致,但其继承的⽗类对象属性值不⼀致,在⽐较的时候会出现⽐较结果不对的情况。
举个简单的例⼦:
这边先定义⼀个分类对象 Parent,有⼀个属性:code
@Data
public class Parent {
/**
* ⽗类编码
*/
private String code;
}
再定义⼀个⼦类对象 Child,⼀⼀个属性:name
@Data
public class Child extends Parent {
/**
* ⼦类名称
*/
private String name;
}
在⽅法中 new 两个 Child 对象:childTest1、childTest2
对这两个 Child 对象的⾃有属性 name 都赋值为:Child;但是对继承的⽗类属性 code 进⾏不同的赋值
Child childTest1 = new Child();
childTest1.setCode("1");
childTest1.setName("child");
Child childTest2 = new Child();
childTest2.setCode("2");
childTest2.setName("child");
根据使⽤过程中,这两个对象肯定是不⼀样的,但是,在不加 @EqualsAndHashCode(callSuper = true) 注解的情况下对这两个对象进⾏⽐较得到的结果却是 true
boolean isSame = Objects.equals(childTest1,childTest2);
log.info("testEquals -> childTest1:{}, childTest2:{}", childTest1, childTest2);
log.info("testEquals -> :{}", isSame);
@EqualsAndHashCode(callSuper = true) 注解的作⽤就是将其⽗类属性也进⾏⽐较,下⾯是 Child 类加了注解后运⾏的结果:
@EqualsAndHashCode(callSuper = true)
@Data
public class Child extends Parent {
equals()方法/**
* ⼦类名称
*/
private String name;
}
因为 @Data ⽣成的 equals ⽅法,只对该类⾥⾃有的属性进⾏了⽐较;
下⾯看下加与不加注解的时候编译后的 Child 类
(1)⽆ @EqualsAndHashCode(callSuper = true) 注解
public boolean equals(Object o){
if (o == this) {
return true;
}
if (!(o instanceof Child)) {
return false;
}
Child other = (Child)o;
if (!other.canEqual(this)) {
return false;
}
Object this$name = getName();Object other$name = Name();return this$name == null ? other$name == null :
this$name.equals(other$name);
}
(2)有 @EqualsAndHashCode(callSuper = true) 注解
public boolean equals(Object o){
if (o == this) {
return true;
}
if (!(o instanceof Child)) {
return false;
}
Child other = (Child)o;
if (!other.canEqual(this)) {
return false;
}
if (!super.equals(o)) {
return false;
}
Object this$name = getName();Object other$name = Name();return this$name == null ? other$name == null :
this$name.equals(other$name);
}
对⽐⼀下,可以看到加了注解之后多了 super.equals ⽅法
if (!super.equals(o)) {
return false;
}
细⼼的朋友会发现,在⽤ log 打印两个对象的时候,toString ⽅法只打印了⼦类属性,隐藏了⽗类属性,这⾥其实和 equals ⽅法⼀
样,@Data 注解⽣成的 toString ⽅法也只包含了⼦类⾃有属性。
解决⽅案⼀样,加上 @ToString(callSuper = true) 注解,其实这⾥真正重要的是注解中的属性,callSuper = true,加上注解后打印结果如下:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论