@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 { /** * 子類名稱 */ 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 = other.getName();
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 = other.getName();
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,加上注解后打印結果如下: