當前位置: 妍妍網 > 碼農

盤點 Lombok 的幾個騷操作

2024-03-30碼農

點選關註公眾號,Java幹貨 及時送達 👇

本文不討論對錯,只講騷操作。

有的方法看看就好,知道可以這麽用,但是否套用到實際開發中,那就仁者見仁,智者見智了。

一萬個讀者就會有一萬個哈姆雷特,希望這篇文章能夠給您帶來一些思考。

耐心看完,你一定會有所收獲。

@onX

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

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

例如下面這段程式碼

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public classMyService{
privatefinal AnotherService anotherService;
}

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

@Service
public classMyService{
privatefinal AnotherService anotherService;
@Autowired
publicMyService(AnotherService anotherService){
this.anotherService = anotherService;
}
}

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

  • MyService 生成了一個建構函式,該建構函式接受一個 AnotherService 型別的參數。

  • 由於建構函式上有 @Autowired 註解,Spring 會自動尋找合適的 AnotherService bean 例項並註入到 MyService 中。

  • 這種方式結合了 Lombok 的自動程式碼生成功能和 Spring 的依賴註入功能,使得程式碼更為簡潔。

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

    @Delegate

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

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

    // 一個類,有一個方法
    public classA{
    publicvoidsayHello(){
    System.out.println("Hello");
    }
    }
    // 一個類,委托了A類的方法
    public classB{
    @Delegate// 委托A類的方法
    private A a = new A();
    publicstaticvoidmain(String[] args){
    B b = new B();
    b.sayHello(); // 呼叫A類的方法
    }
    }

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

    @Cleanup

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

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

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

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

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

    @Cleanup("release") MyResource resource = new MyResource();

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

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

    @Singular 和 @Builder 組合

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

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

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

    @Data
    @Builder
    public classUser{
    private String name;
    privateint age;
    @Singular
    private List<String> hobbies;
    }
    // 使用 @Builder 和 @Singular 生成的方法
    User user = User.builder()
    .name("練習時長兩年半")
    .age(28)
    .hobby("籃球"// 添加單個元素
    .hobby("唱歌"// 添加單個元素
    .hobbies(Arrays.asList("跳舞""其他")) // 添加整個集合
    .build(); // 構造 User 物件

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

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

    User user = User.builder()
    .name("簽")
    .age(28)
    .hobby("說唱")
    .hobby("跳舞")
    .clearHobbies() // 清空集合欄位
    .hobby("踩縫紉機"// 重新添加元素
    .build();

    但需要註意的是,如果你的類繼承了一個父類,那麽 @Builder 只會生成當前類的欄位和參數,不包括父類的。

    @With

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

    @With
    public classPerson{
    private String name;
    privateint age;
    }
    Person person = new Person("Alice"30);
    // 建立一個新的 Person 物件,其 name 為 "Alice",但 age 為 31
    Person updatedPerson = person.withAge(31); 

    結尾

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

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


    END


    看完本文有收獲?請轉發分享給更多人

    關註「Java編程鴨」,提升Java技能

    關註Java編程鴨微信公眾號,後台回復:碼農大禮包可以獲取最新整理的技術資料一份。涵蓋Java 框架學習、架構師學習等!

    文章有幫助的話,在看,轉發吧。

    謝謝支持喲 (*^__^*)