lombok——@EqualsAndHashCode(callSuper = true)注解的和exclude使用


  • 此注解會生成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 {
/**
* 子類名稱
*/
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,加上注解后打印結果如下:


以上
————————————————
版權聲明:本文為CSDN博主「快看,飛天豬」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_42888567/java/article/details/105145024


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM