優雅的Java工具庫Lombok

來源:互聯網
上載者:User

標籤:factor   actor   file   的區別   get   lis   許可權   eth   相關   

優雅的Java工具庫Lombok

最近在公司的項目中看到了對於Lombok的應用,通過@Data註解標註POJO,省略了大量的getter/setter代碼,原先冗長的POJO在瘦身之後直接變得乾淨、清爽,程式員再也不需要去關注那些長長的方法,只需要集中注意力於欄位field之中

Lombok簡介

Lombok是一個非常實用的Java工具庫,有效地簡化Java代碼的冗長。它通過註解如@Data可以直接為Java bean在編譯期動態地產生欄位的getter/setter方法,使用註解@NoArgsConstructor 和@AllArgsConstructor 為Java bean添加無參構造器和有參構造器,甚至可以在Java代碼中使用val和var聲明一個動態變數,而無需再指定具體的變數類型,區別只是val聲明的變數為final。Lombok還提供了delombok供產生Javadoc,delombok在運行時會將註解@Data轉換成getter/setter方法,然後移除@Data註解,如果哪天不再需要Lombok,也只需要簡單運行delombok即可。Lombok的構建支援maven和gradle,同時eclipse、myeclipse和idea等主流IDE也都和lombok相容,所以可以放心大膽地使用Lombok,不用擔心IDE的編譯檢查問題。

Lombok栗子Eclipse安裝Lombok支援

官網Lombok https://projectlombok.org/download 下載jar包或者通過構建工具maven,gradle下載jar包

雙擊jar包,jar包內的安裝器會自動運行尋找eclipse

點擊【Install/Update】

引入Lombok依賴
    <dependency>        <groupId>org.projectlombok</groupId>        <artifactId>lombok</artifactId>        <version>1.18.2</version>        <scope>provided</scope>    </dependency>
Lombok註解使用

Lombok的註解分為穩定版本和實驗版本,這裡主要介紹穩定版本,因為實驗版本的支援目前和IDE不是很好

@Getter/@Setter註解

@Getter/@Setter註解的作用就是為欄位添加getter/setter方法,可標註在類上,也可標註在欄位上。標註在類上表示所有的非靜態(no-static)欄位都會產生相應的getter/setter方法,標註在欄位上表示只為這個欄位產生,且會覆蓋標註在類上的註解。可設定存取層級,預設為public。@Setter不可以標註final欄位

@[email protected]public class SetterExample {        @Getter(value=AccessLevel.PRIVATE)@Setter    private String name;        //[email protected]__({@AnnotationsHere})    @Setter([email protected]__({@Deprecated}))    private String age;        //[email protected]__({@AnnotationsHere})    @Setter([email protected]__({}))    private String sex;        public static void main(String[] args) {        SetterExample se = new SetterExample();        se.setName("zhangsan");        se.setAge("16");        System.out.println(se.getAge());        System.out.println(se.getName());    }}

Lombok提供了onX的實驗屬性,分別為:onMethod, onParam, onConstructor,用於向產生的方法,構造器,參數添加註解

反編譯後結果

@NonNull註解

@NonNull註解標註方法和構造器的參數,如果參數為null,則會拋出null 指標異常,不需要在代碼中進行null檢測

public class NonNullExample {        @Getter    private String name;        public NonNullExample(@NonNull String name){        this.name = name;    }        public static void main(String[] args){        String name = null;        NonNullExample nne = new NonNullExample(name);        System.out.println(nne.getName());    }}
@ToString註解

@ToString註解產生toString()方法

@ToStringpublic class ToStringExample {    @ToString.Exclude    private String name;        @ToString.Include    private String age;        private String sex;        public static void main(String[] args) {        ToStringExample tse = new ToStringExample();        System.out.println(tse.toString());    }}

屬性includeFieldNames,預設為true,包含屬性值

屬性callSuper,預設為false,調用父類實現

屬性onlyExplicitlyIncluded,預設為false,僅包含明確包含的屬性

@ToString.Exclude 標註屬性值不包含在toString()方法中

@ToString.Include標註屬性值包含在toString()方法中

@EqualsAndHashCode

@EqualsAndHashCode註解產生equals()和hashcode()方法,註解的屬性和@ToString類似

@EqualsAndHashCodepublic class EqualsAndHashcodeExample {    private String name;    private String age;    private String sex;        public static void main(String[] args) {        EqualsAndHashcodeExample ehe1 = new EqualsAndHashcodeExample();        EqualsAndHashcodeExample ehe2 = new EqualsAndHashcodeExample();        System.out.println(ehe1.equals(ehe2));        System.out.println(ehe1.hashCode());        System.out.println(ehe2.hashCode());    }}
@[email protected]@AllArgsConstructor

@NoArgsConstructor : 產生一個無參數的構造方法

@NoArgsConstructor(force=true, staticName="newInstance")public class NoArgsConstructorExample {    //包含的final欄位如果沒有初始化,需要加上force=true強制初始化,否則編譯錯誤    private final String name;        //不會進行null檢查    @NonNull    @Getter    private String age;        private String sex;        public static void main(String[] args) {        NoArgsConstructorExample nace1 = new NoArgsConstructorExample();        System.out.println(nace1.getAge());        NoArgsConstructorExample nace2 = NoArgsConstructorExample.newInstance();        System.out.println(nace2.getAge());    }}

@RequiredArgsConstructor:會產生一個包含常量,和標識了NotNull的變數 的構造方法。

@RequiredArgsConstructor(staticName="newInstance")public class RequiredArgsConstructorExample {    private final String name;        @NonNull    @Getter    private String age;        private String sex;        public static void main(String[] args) {        RequiredArgsConstructorExample race1 = new RequiredArgsConstructorExample("lisi", "18");        System.out.println(race1.getAge());        RequiredArgsConstructorExample race2 = RequiredArgsConstructorExample.newInstance("zhangsan", "16");        System.out.println(race2.getAge());    }}

@AllArgsConstructor:會產生一個包含所有變數,同時如果變數使用了NotNull annotation , 會進行是否為空白的校正

@AllArgsConstructor(staticName="newInstance")public class AllArgsConstructorExample {    private final String name;        @NonNull    @Getter    private String age;        private String sex;    public static void main(String[] args) {        AllArgsConstructorExample aace1 = new AllArgsConstructorExample("zhangsan", "18", "female");        System.out.println(aace1.getAge());        AllArgsConstructorExample aace2 = AllArgsConstructorExample.newInstance("lisi", "16", "male");        System.out.println(aace2.getAge());    }}

注意:三個註解產生的構造器都可以指定存取權限,同時也可以提供一個靜態方法來供調用。三個註解的區別在於對final和@NonNull欄位的處理不同

另外關於staticName屬性,Lombok源碼注釋如下:

If set, the generated constructor will be private, and an additional static ‘constructor‘ is generated with the same argument list that wraps the real constructor.

很明顯三個註解都是可以使用構造器直接建立對象的,也可以使用靜態方法建立對象,不知道這段注釋是什麼意思???

@Data註解

等同於@ToString, @EqualsAndHashcode, @Getter, @Setter和@RequiredArgsConstructor一起使用

@Value

@Value註解為不可變類型的@Data,是@Data的一個變種。它標註的類和欄位都會被聲明為final

@Builder註解

@Builder註解為類產生builder api以供調用。Builder是一種解決包含數量巨大且繁雜的欄位的類的一種構建方式。

假如一個類有幾十個欄位,那麼該如何設計這個類呢?

方法一:將幾十個欄位都添加在建構函式中。簡單粗暴,而且在建構函式中為欄位初始化也能夠保證對象能夠正確建立。缺點就是幾十個參數只會導致你在建立對象時記錯參數的位置,導致不必要的麻煩。

方法二:依賴注入。Spring的核心功能之一就是依賴注入,藉助這種思想,我們通過無參構造建立一個對象,然後通過setter方法設定必需的屬性。這種方式可以根據需求初始化相關屬性,且邏輯清晰,但也會造成代碼繁瑣,需要調用多次setter方法。

方法三:Builder模式。建造者模式的思想就是將一個大的類的構建分為幾部分建立,從而簡化建立的複雜性。

@Builderpublic class BuilderExample {    private String name;    private String age;    private String sex;    public static void main(String[] args) {        BuilderExample be = BuilderExample.builder().name("zhangsan").age("16").sex("male").build();                System.out.println(BuilderExample.builder().name("zhangsan").age("16").sex("male"));    }}

@Log

@Log註解為類添加一個日誌對象log,類型為java.util.logging.Logger

這個類有很多變種,詳情如下:

@CommonsLogprivate static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);@Floggerprivate static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass();@JBossLogprivate static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);@Logprivate static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());@Log4jprivate static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);@Log4j2private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);@Slf4jprivate static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);@XSlf4jprivate static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
@CleanUp註解

@CleanUp註解用於關閉資源,調用資源的close()方法

public class CleanUpExample {        @SneakyThrows({FileNotFoundException.class, Exception.class})    public static void main(String[] args) {        File file = new File("C:/Users/wang2/Desktop/11.jpg");        @Cleanup        FileInputStream is = new FileInputStream(file);        @Cleanup        FileOutputStream os = new FileOutputStream(new File("C:/Users/wang2/Desktop/111.jpg"));                byte[] buffer = new byte[1024];        int length = 0;        while((length = is.read(buffer)) != -1){            os.write(buffer, 0, length);        }    }}

注意:拋出的異常被@SneakyThrows捕獲了

@SneakyThrows註解

Sneaky的意思是偷偷摸摸地,@SneakyThrows註解的作用就是取代try...catch代碼塊,自動產生相應的try...catch代碼塊

優雅的Java工具庫Lombok

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.