盤點Lombok的幾個操作,你記得了嗎?

例如 onConstructor, oMethod, 和 onParam 允許你在產生的程式碼中註入自訂的註解。一個常見的用例是結合Spring 的 @Autowired。

在Spring 的元件(如@Service、@Controller、@Component、@Repository 等)中使用@RequiredArgsConstructor(onConstructor = @__(@Autowired)),可以讓Lombok 在產生建構函式時也加上@Autowired 註解,這樣,Spring 就可以自動注入所需的依賴。

例如下面這段程式碼

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MyService {
    private final AnotherService anotherService;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

上述程式碼片段使用 Lombok 和Spring 註解,Lombok 會為其產生以下程式碼

@Service
public class MyService {
    private final AnotherService anotherService;

    @Autowired
    public MyService(AnotherService anotherService) {
        this.anotherService = anotherService;
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

從生成的程式碼可以看出:

  • 為 MyService 產生了一個建構函數,該建構函數接受一個 AnotherService 類型的參數。
  • 由於建構子上有 @Autowired 註解,Spring 會自動尋找適當的 AnotherService bean 實例並注入到 MyService 中。

這種方式結合了 Lombok 的自動程式碼產生功能和Spring 的依賴注入功能,讓程式碼更簡潔。

但是,使用此技巧時要確保團隊成員都理解背後的意義,以避免混淆。

@代表

@Delegate可以讓你的類別使用其他類別的方法,而不需要自己寫程式碼。

例如,你有一個類別叫做A,它有一個方法叫做sayHello(),你想讓另一個類別B也能用這個方法,那就可以在B類中加上一個A類型的字段,並在這個字段上加上@Delegate註解,這樣,B類別就可以直接呼叫sayHello()方法,就像它是自己的方法一樣。看個例子:

// 一个类,有一个方法
public class A {
    public void sayHello() {
        System.out.println("Hello");
    }
}

// 一个类,委托了A类的方法
public class B {
    @Delegate // 委托A类的方法
    private A a = new A();

    public static void main(String[] args) {
        B b = new B();
        b.sayHello(); // 调用A类的方法
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

這樣寫最大的好處就是可以避免類別的層次過深或耦合過緊,提高程式碼的可讀性和可維護性,各種繼承來繼承去是真的看得頭痛。

@清理

@Cleanup可以自動管理輸入輸出流等各種需要釋放的資源,確保安全地呼叫close方法。

它的使用方法是在聲明的資源前加上@Cleanup,例如:

@Cleanup InputStream in = new FileInputStream("some/file");
  • 1.

這樣,當你的程式碼執行完畢後,Lombok會自動在一個try-finally區塊中呼叫in.close()方法,釋放資源。

如果要釋放資源的方法名稱不是close,也可以指定要呼叫的方法名,例如:

@Cleanup("release") MyResource resource = new MyResource();
  • 1.

Lombok會自動在try-finally區塊中呼叫resource.release()方法,釋放資源。

可以看到,這比手動寫入try-finally要簡潔得太多了,只要使用@Cleanup就能管理任何有無參方法的資源,指定正確的方法名稱即可。

@Singular 和@Builder 組合

@Builder讓你的類別支援鍊式構造,而@Singular讓集合類型欄位可以更方便的維護。

@Singular註解可以用在集合類型的欄位上,它會產生兩個方法,一個是加入單一元素的方法,一個是加入整個集合的方法。這兩個方法可以和 @Builder 產生的其他方法一起鍊式調用,給你的類別的所有欄位賦值。

這麼講可能有點懵,直接看範例:

@Data
@Builder
public class User {
    private String name;
    private int age;
    @Singular
    private List<String> hobbies;
}

// 使用 @Builder 和 @Singular 生成的方法
User user = User.builder()
    .name("练习时长两年半")
    .age(28)
    .hobby("篮球") // 添加单个元素
    .hobby("唱歌") // 添加单个元素
    .hobbies(Arrays.asList("跳舞", "其他")) // 添加整个集合
    .build(); // 构造 User 对象
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

可以看出,使用 @Singular 註解的好處是,你可以靈活地添加集合類型的字段,而不需要自己創建和初始化集合物件。

另外,使用 @Singular 註解產生的集合字段,在呼叫 build() 方法後,會被轉換為不可變的集合,這樣可以保證物件的不變性和執行緒安全性。你也可以使用 clear() 方法來清空集合字段,例如:

User user = User.builder()
    .name("签")
    .age(28)
    .hobby("说唱")
    .hobby("跳舞")
    .clearHobbies() // 清空集合字段
    .hobby("踩缝纫机") // 重新添加元素
    .build();
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

但要注意的是,如果你的類別繼承了一個父類,那麼 @Builder 只會產生目前類別的欄位和參數,不包括父類的。

@和

允許你建立一個新的對象,該對像是當前對象的副本,但某些欄位的值已被更改。

@With  
public class Person {  
    private String name;  
    private int age;  
}  
  
Person person = new Person("Alice", 30);  
// 创建一个新的 Person 对象,其 name 为 "Alice",但 age 为 31
Person updatedPerson = person.withAge(31);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

結尾

請注意,儘管Lombok 提供了許多方便的功能,但過度使用或不當使用可能會導致程式碼難以理解和維護。

因此,在使用這些功能時,請務必始終保持審慎,並且要充分考慮其影響。