Lombok——程式碼簡化

蜗牛旅行1899發表於2024-04-21

lombok是一個簡化程式碼的類庫,可以使Java程式碼看起來更簡潔,本質是在編譯階段會根據註解生成一些程式碼。

搭建環境比較簡單,

第一步,引入lombok的Jar包。

第二步,在IDE上安裝外掛,例如idea的外掛庫直接搜尋lombok即可。

它的註解,按照階段分為兩類,stable(穩定版), experimental(測試版),本文只介紹穩定版本。

根據功能劃分為兩類,新增在類上,簡化類的註解。新增在方法上,簡化方法的註解。

1、類

1.1 實體Bean

  1.1.1 getter & setter

  描述:為實體Bean新增getter和setter方法。

  原理:

   編譯前程式碼:

@Getter 
private String name

   編譯後程式碼:

public String getName(){ 
  return this.name
};

  註解屬性:

    AccessLevel:get&set方法的修飾符,預設為public,可選值有private, public, protected, package, none。當為none時,不會生成get和set方法,最典型的就是序列化ID。

  場景:使用頻率非常高,新增在實體bean上,忽略序列化ID。

  示例:略

  1.1.2 toString

  描述:生成toString方法。預設的格式為”類名(fieldname=fieldValue)”,擁有多個欄位,會有多組fieldname=fieldValue。

  原理:

    編譯前程式碼: 

@ToString
public class Test { 
	private String name;
}

    生成程式碼:

public String toString(){
	return "Test(name=" + this.name +")"; 
}

  註解屬性:

    @ToString.Exclude:新增在欄位上時,不包含該欄位。

    onlyExplicitlyIncluded:預設情況下toString會包含所有欄位,並排除掉@ToString.Exclude,設定該屬性之後,toString只會包含@ToString.include的欄位。

    @ToString.include:包含該欄位。

  場景:頻率較低,主流方式是將物件轉換為JSON字串。

  示例:略

1.1.3 equalAndHashCode

  描述:生成equals和hashCode方法。

  原理:略。

  註解屬性:與@ToString類似,包含或排除某個欄位。略。

  場景:頻率較低。

  示例:略。

1.1.4 xxConstructor

  描述:生成構造器,有三種,

  @NoArgsConstructor:無參註解

  @RequiredArgsConstructor:有部分欄位作為引數的構造器。

  @AllArgsConstructor:有所有欄位作為引數的構造器。

原理:

註解屬性:

場景:

示例:

1.1.5 data

描述:@Getter,@Setter,@EqualAndHashCode, @RequiredArgsConstructor的總和。

原理:略。

註解屬性:略。

場景:略。

示例:略。

1.1.6 value

  描述:與@data註解相似,區別在於生成不可變類,所有欄位新增final修飾符,不生成set方法。

  原理:略。

  註解屬性:

    @NonFinal:在欄位上新增@NonFinal,生成時,不會新增final修飾符。

  場景:略。

  示例:略。

  1.1.7 with

  描述:生成一個withXX方法根據欄位進行比較,若欄位值相同,返回當前物件,欄位值不同,新建立一個物件,引數為該欄位值。

  原理:

    編譯前程式碼: 

@With 
private String name;

    生成程式碼:

public User withName(String name){
   return this.name == name ? this : new User(name);
}

  註解屬性:

    AccessLevel:與getter&setter註解中的同名屬性含義想相同,此處指定withXX方法的修飾符。

  場景:略。

  示例:略。

  1.1.8 builder

  描述:用構造器模式的方式生成相關的方法。例如User物件,

User user = User.builder()

.age(xx) // 年齡

.name(xx) // 姓名

.address(xx); // 地址。

  原理:略。

  註解屬性:

   @Builder.Default:無需指定,自動生成的,例如new Date()。

   @Singular:在集合屬性上新增。生成的方法會有不同。

  場景:若寫builder方法,通常還需要新增一些邏輯,不會像set方法那樣簡單,實際使用頻率較低。

  示例:略。

1.2 公共屬性

  為物件新增一個常用的,公共的物件例項,例如,最常見的log。

  1.2.1 Log

  描述:為物件新增一個公共屬性log。不同註解新增的log型別不同。

@commonLog: org.apache.commons.logging.Log

@Flogger: com.google.common.flogger.FluentLogger

@JBossLog: org.jboss.logging.Logger

@Log: java.util.Logging.Logger

@Log4j: org.apache.log4j.log

@Log4j2: org.apache.logging.log4j.Logger

@Slf4j: org.slf4j.Logger

@CustomLog:org.apache.commons.logging.LogFactory.getLog("CounterLog")

1.2.2 Locked

  描述:在方法上新增鎖的註解,生成一個鎖的例項物件。有三種型別註解

  @Locked:建立ReentrantLock例項。

  @Locked.read 或 @Locked.write:建立ReentrantReadWriteLock例項。

  原理:

    編譯前程式碼: 

@Locked("baseLock")
public void test() {
	System.out.println("hello Java");
}

    生成程式碼:

private final Lock baseLock = new ReentrantLock();
public void foo() {
	this.baseLock.lock();
	try {
	  System.out.println("bar");
	} finally {
	  this.baseLock.unlock();
	}
}

  註解屬性:

    value:指定屬性的名稱。

場景:略。

示例:略。

1.2.3 synchronized

  描述:在方法上新增該註解,會生成一個公共屬性$lock或$LOCK。

  在例項方法上新增此註解時,會自動生成$lock屬性,並synchronized該欄位。

  在靜態方法上新增此註解時,會自動生成$LOCK屬性,並synchronized該欄位。

  原理:

    編譯前程式碼: 

@synchronized
public void test(){};

    生成程式碼:

private final Object $lock = new Object[0];
public void test{
	synchronized($lock){
		// 程式碼塊
	}
}

  註解屬性:

    value:指定屬性的名稱。例如@synchronized(“syncProp”),公共屬性名稱從$lock或$LOCK替換為syncProp。

  場景:略。

  示例:略。

2、方法

2.1 公共

2.1.1 sneakyThrows

  描述:方法上無需宣告顯示異常。

  原理:

    編譯前程式碼: 

@SneakyThrows("IOException")
public void test(){};

    生成程式碼:

public void test(){
	try{
        // test程式碼塊。
	}catch(IOException e){
		throw Lombok.sneakyThrow(e);
	}
}

  註解屬性:無。

  場景:IO操作方法時比較多。

  示例:略。

2.2 變數

  2.2.1 var & val

  描述:定義變數,無需指定具體型別,類似於JS。

  原理:

    編譯前程式碼: 

var str = new String();

    生成程式碼:

String str = new String();

  註解屬性:無。

  場景:通常變數名根據型別生成,反而不方便。

  示例:var user = new User();

  val註解和它是相似的,唯一的區別在於生成的變數帶有final修飾符。

  2.2.2 cleanup

  描述:新增在變數上,生成finally方法,呼叫變數的close方法。

  原理:

    編譯前程式碼: 

@CleanUp 
Connection conn = new Connection();

    生成程式碼: 

Connection conn = new Connection();
try{
	// new Connection的後續程式碼
}finally{
	if(conn!=null){
		conn.close();
	}
}

  註解屬性:

    value:指定方法的名稱,例如@CleanUp(“destory”),會呼叫destory方法。

  場景:沒有try, catch,程式碼簡潔很多。

  示例:@CleanUp InputStream input = new FileInputStream(“fileName”)

2.3 引數

  2.3.1 nonNull

  描述:判斷引數非空。

  原理:

    編譯前程式碼: 

public void test(@NonNull String name)

    生成程式碼: 

public void test(String name){
  if(name == null){
	      throw new NullPointerException(“name is marked non-null but is  null”)
  }
  // test方法的後續程式碼
}

  註解屬性:略。

  場景:影響程式碼的閱讀,通常不會使用。

  示例:略。

相關文章