Lombok插件的簡介

官網: projectlombok.org/html

官方文檔: projectlombok.org/api/lombok/…java

參考資料:api

www.jianshu.com/p/2543c71a8…數組

blog.csdn.net/zhaoyanjun6…markdown

1 Lombok引入

==未使用lombok的Java的Bean:==框架

public class DepartMent {

    private String name;

    public DepartMent() {
    }

    public DepartMent(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DepartMent that = (DepartMent) o;
        return Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

    @Override
    public String toString() {
        return "DepartMent{" +
                "name='" + name + '\'' +
                '}';
    }
}
複製代碼

==使用lombok的Java的Bean:==ide

@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EqualsAndHashCode
public class DepartMent {
    private String name;
}  
複製代碼

總結:oop

lombok的出現,是爲了簡化Java的Bean對象,將大量重複,沒有技術意義的代碼省略,不只能使代碼整潔美觀,還能人們將注意力放到更重要的業務代碼中.ui

使用前準備:this

1 在IDEA中plugins中安裝Lombok插件,重啓IDEA.

image-20210406213944545

2 添加lombok座標

<dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <version>1.18.16</version>
                </dependency>
複製代碼

2 Lombok常見註解使用

1 @Data

@Data註解,自動生成對象屬性的getter方法,setter方法,equals方法,hashCode方法,toString方法,無參構造方法.

厲害的童鞋提醒滴

@Data
public class DepartMent {
    private String name;
}  
複製代碼

等同於:

public class DepartMent {
    private String name;
    
 	public DepartMent() {}
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DepartMent that = (DepartMent) o;
        return Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
}
複製代碼

2 @AllArgsConstructor

@AllArgsConstructor註解, 對象的全參數構造

@NoArgsConstructor
public class DepartMent {
    private String name;
}  
複製代碼

等同於:

public class DepartMent {
    private String name;

    public DepartMent(String name) {
        this.name = name;
    }

}
複製代碼

3 @NoArgsConstructor

@NoArgsConstructor註解,對象的無參構造

@NoArgsConstructor
public class DepartMent {
    private String name;
}  
複製代碼

等同於:

public class DepartMent {
    private String name;

    public DepartMent() {}

}
複製代碼

4 @ToString

@ToString註解,對象的toString方法

@ToString
public class DepartMent {
    private String name;
}  
複製代碼

等同於:

public class DepartMent {
    private String name;
    
    @Override
    public String toString() {
        return "DepartMent{" +
                "name='" + name + '\'' +
                '}';
    }
}  
複製代碼

5 @EqualsAndHashCode

@EqualsAndHashCode註解,對象的equals和hashcode方法.

@EqualsAndHashCode
public class DepartMent {
    private String name;
}  
複製代碼

等同於:

public class DepartMent {
    private String name;
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        DepartMent that = (DepartMent) o;
        return Objects.equals(name, that.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }
} 
複製代碼

6 @Getter/@Setter

@Getter/@Setter註解,對象的get/set方法

@Getter
@Setter  
public class DepartMent {
    private String name;
} 
複製代碼

等同於:

public class DepartMent {
    private String name;
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
複製代碼

7 @Slf4j

@Slf4j註解,日誌打印,至關於public static final Logger log = LoggerFactory.getLogger(類名.class);

@Slf4j 
public class DepartMent {
    private String name;
    
  public static void main(String[] args) {
        log.info("日誌: {}" + "Hello World!");
    }
} 
複製代碼

等同於:

public class DepartMent {
    private String name;
    
    public static final Logger log = LoggerFactory.getLogger(DepartMent.class);
    
    public static void main(String[] args) {
        log.info("日誌: {}" + "Hello World!");
    }
} 
複製代碼

8 @NonNull

@NonNull註解, 對象的成員變量和參數,標識不能爲空,不然拋出空指針異常.

public class DepartMent {
    @NonNull
    private String name;
    
    public String getName() {
        return name;
    }

    public void setName(@NonNull String name) {
        this.name = name;
    }
} 
複製代碼

9 @Value

@Value註解, 把對象爲final類,把成員變量默認定義private final,且不生成set方法.

@Value
public class DepartMent {
    private String name;
} 
複製代碼

等同於:

public final class DepartMent {
    private final String name;
} 
複製代碼

10 @Builder

@Builder註解, 給類添加構造者模式

@Builder
public class DepartMent {
    private String name;
} 
複製代碼

等同於:

public class DepartMent {
  
   private String name;
    
   DepartMent(String name) {
        this.name = name;
    }
   public static DepartMent.DepartMentBuilder builder() {
        return new DepartMent.DepartMentBuilder();
    }
    
     public static class DepartMentBuilder {
   	 	private String name;
         DepartMentBuilder(){};
         
         public DepartMent.DepartMentBuilder name(String name) {
            this.name = name;
            return this;
        }
         
         public DepartMent build() {
            return new DepartMent(this.name);
        }
         public String toString() {
            return "DepartMent.DepartMentBuilder( name=" + this.name +")";
        }
   }

} 
複製代碼

11 @Synchronized

@Synchronized註解,加一個同步鎖

public class DepartMent {
   
    private String name;
    
    //普通方法,至關於對象鎖
    @Synchronized
    void before() {
       //代碼邏輯
    }
    
    //靜態方法,至關於類鎖
    @Synchronized
    static void after() {
       //代碼邏輯
    }   

} 
複製代碼

等同於:

public class DepartMent {
    private final Object $lock = new Object[0];
    private static final Object $LOCK = new Object[0];
    private String name;
    

    void before() {
        Object var1 = this.$lock;
        synchronized(this.$lock) {
             //代碼邏輯
        }
    }
    
    static void after() {
	    Object var0 = $LOCK;
        synchronized($LOCK) {
             //代碼邏輯
        }
     
    }   

} 
複製代碼

12 @SneakyThrows

@SneakyThrows註解, 等同於try/catch 捕獲異常.

public class DepartMent {
    private String name;
    
    @SneakyThrows
    public void init(){
        int a = 1 / 0;
    }
} 
複製代碼

等同於:

public class DepartMent {
    private String name;
    
    public void init(){
        try{
        int a = 1 / 0;
        }catch(Exception e){
            //處理
        }
    }
} 
複製代碼

13 @Cleanup

@Cleanup註解,自動關閉資源,例如IO流對象.

public class DepartMent {
    private String name;
    
    public void init(){
       @Cleanup InputStream in = new InputStream(); 
    }
}
複製代碼

等同於:

public class DepartMent {
    private String name;
    
    public void init(){
        try{          
       		InputStream in = new InputStream();  
        }finally{
            in.close();
    }
}
複製代碼

14 @Accessors

@Accessors註解,存取器,控制getter和setter方法的形式.註解有三個屬性. fluent fluent默認爲false,若是爲true,則getter和setter方法的方法名都是屬性名(以下name),且setter方法返回當前對象.(以下DepartMent )

@Data
@Accessors(fluent = true)
public class DepartMent {
    private String name;
    
     public String name() {
        return name;
    }

    public DepartMent name(String name) {
       //Xxx
    }   
}
複製代碼

chain chain默認爲false,若是爲true,setter方法返回當前對象.(以下DepartMent )

@Data
@Accessors(chain = true)
public class DepartMent {
    private String name;
    
     public String getName() {
        return name;
    }

    public DepartMent setName(String name) {
       //Xxx
    }   
}
複製代碼

prefix prefix默認爲空的字符數組.可自定義前綴.(以下f),getter和setter方法會忽視屬性名前的前綴.(剩下按照駝峯命名規則)

@Data
@Accessors(prefix = "f")
public class DepartMent {
    private String fname;
    
     public String name() {
        return name;
    }

    public void name(String name) {
       //Xxx
    }   
}
複製代碼

3 Lombok原理

jdk1.6,javac支持JSR 269 Pluggable Annotation Processing API規範,程序實現該規範,在javac運行時,就能夠調用.

Lombok就是實現了該規範的程序.在javac過程當中的工做流程:

  • 1 javac對源代碼分析,生成一棵抽象語法樹(AST)

  • 2 javac編譯過程調用Lombok程序

  • 3 插件對獲得的AST處理,找到註解地點,修改語法樹,添加註解定義響應的樹節點

  • 4 javac將修改後的語法樹(AST)生成字節碼文件

4 關於Lombok總結

關於Lombok的使用,衆說紛紜,有人支持,有份反對. 新的技術出現,一定解決了一些生活中的問題,也必然帶來新的問題.

Lombok的使用,給代碼帶來了簡潔美觀, 節省大量基礎代碼.同時也帶來了不少問題,如一人使用,全人必須使用;項目升級,新的框架可否使用該插件?

我相信Lombok插件將來發展會愈來愈好.

tips:

IDEA2020.3版本,已經將Lombok做爲內置插件.SpringBoot的2.1.x版本在Starter中內置了Lombok依賴.

相關文章
相關標籤/搜索