Java效率工具Lombok使用及原理

還在編寫無聊枯燥又難以維護(hù)的POJO嗎芹啥?潔癖者的春天在哪里?請看Lombok

在過往的Java項(xiàng)目中忍抽,充斥著太多不友好的代碼:POJO的getter/setter/toString捶索;異常處理插掂;I/O流的關(guān)閉操作等等,這些樣板代碼既沒有技術(shù)含量腥例,又影響著代碼的美觀辅甥,Lombok應(yīng)運(yùn)而生。

首先說明一下:任何技術(shù)的出現(xiàn)都是為了解決某一類問題的燎竖,如果在此基礎(chǔ)上再建立奇技淫巧璃弄,不如回歸Java本身。應(yīng)該保持合理使用而不濫用构回。

Lombok的使用非常簡單夏块,下面我們一起來看下:

1)引入相應(yīng)的maven包:

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.18</version>
  <scope>provided</scope>
</dependency>

Lombok的scope=provided,說明它只在編譯階段生效纤掸,不需要打入包中脐供。事實(shí)正是如此,Lombok在編譯期將帶Lombok注解的Java文件正確編譯為完整的Class文件借跪。

2)添加IDE工具對Lombok的支持:

IDEA中引入Lombok支持如下:
點(diǎn)擊File-- Settings設(shè)置界面政己,安裝Lombok插件:

點(diǎn)擊File-- Settings設(shè)置界面,開啟Annocation Processors
開啟該項(xiàng)是為了讓Lombok注解在編譯階段起到作用掏愁。

Eclipse的Lombok插件安裝可以自行百度歇由,也比較簡單,值得一提的是果港,由于Eclipse內(nèi)置的編譯器不是Oracle javac沦泌,而是eclipse自己實(shí)現(xiàn)的Eclipse Compiler for Java (ECJ).要讓ECJ支持Lombok,需要在eclipse.ini配置文件中添加如下兩項(xiàng)內(nèi)容:

-Xbootclasspath/a:[lombok.jar所在路徑]

-javaagent:[lombok.jar所在路徑]

3)Lombok實(shí)現(xiàn)原理:

自從Java 6起辛掠,javac就支持“JSR 269 Pluggable Annotation Processing API”規(guī)范谢谦,只要程序?qū)崿F(xiàn)了該API,就能在javac運(yùn)行的時(shí)候得到調(diào)用。

Lombok就是一個(gè)實(shí)現(xiàn)了"JSR 269 API"的程序他宛。在使用javac的過程中船侧,它產(chǎn)生作用的具體流程如下:

  1. javac對源代碼進(jìn)行分析,生成一棵抽象語法樹(AST)
  2. javac編譯過程中調(diào)用實(shí)現(xiàn)了JSR 269的Lombok程序
  3. 此時(shí)Lombok就對第一步驟得到的AST進(jìn)行處理厅各,找到Lombok注解所在類對應(yīng)的語法樹(AST)镜撩,然后修改該語法樹(AST),增加Lombok注解定義的相應(yīng)樹節(jié)點(diǎn)
  4. javac使用修改后的抽象語法樹(AST)生成字節(jié)碼文件

4) Lombok注解的使用:

POJO類常用注解:

@Getter/@Setter: 作用類上队塘,生成所有成員變量的getter/setter方法袁梗;作用于成員變量上,生成該成員變量的getter/setter方法憔古≌诹可以設(shè)定訪問權(quán)限及是否懶加載等。

package com.trace;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

/**
 * Created by Trace on 2018/5/19.<br/>
 * DESC: 測試類
 */
@SuppressWarnings("unused")
public class TestClass {

    public static void main(String[] args) {

    }


    @Getter(value = AccessLevel.PUBLIC)
    @Setter(value = AccessLevel.PUBLIC)
    public static class Person {
        private String name;
        private int age;
        private boolean friendly;
    }
    public static class Animal {
        private String name;
        private int age;
        @Getter @Setter private boolean funny;
    }

}

在Structure視圖中鸿市,可以看到已經(jīng)生成了getter/setter等方法:

編譯后的代碼如下:[這也是傳統(tǒng)Java編程需要編寫的樣板代碼]

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.trace;

public class TestClass {
    public TestClass() {
    }

    public static void main(String[] args) {
    }

    public static class Animal {
        private String name;
        private int age;
        private boolean funny;

        public Animal() {
        }

        public boolean isFunny() {
            return this.funny;
        }

        public void setFunny(boolean funny) {
            this.funny = funny;
        }
    }

    public static class Person {
        private String name;
        private int age;
        private boolean friendly;

        public Person() {
        }

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

        public int getAge() {
            return this.age;
        }

        public boolean isFriendly() {
            return this.friendly;
        }

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

        public void setAge(int age) {
            this.age = age;
        }

        public void setFriendly(boolean friendly) {
            this.friendly = friendly;
        }
    }
}

@ToString:作用于類锯梁,覆蓋默認(rèn)的toString()方法第岖,可以通過of屬性限定顯示某些字段宁脊,通過exclude屬性排除某些字段。

@EqualsAndHashCode:作用于類须肆,覆蓋默認(rèn)的equals和hashCode

@NonNull:主要作用于成員變量和參數(shù)中内舟,標(biāo)識不能為空合敦,否則拋出空指針異常。

@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor:作用于類上验游,用于生成構(gòu)造函數(shù)充岛。有staticName、access等屬性耕蝉。

staticName屬性一旦設(shè)定崔梗,將采用靜態(tài)方法的方式生成實(shí)例,access屬性可以限定訪問權(quán)限赔硫。

@NoArgsConstructor:生成無參構(gòu)造器炒俱;

@RequiredArgsConstructor:生成包含final和@NonNull注解的成員變量的構(gòu)造器;

@AllArgsConstructor:生成全參構(gòu)造器爪膊。

編譯后結(jié)果:

public static class Person {
    @NonNull
    private String name;
    private int age;
    private boolean friendly;

    public String toString() {
        return "TestClass.Person(name=" + this.getName() + ", age=" + this.getAge() + ")";
    }

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

    public int getAge() {
        return this.age;
    }

    public boolean isFriendly() {
        return this.friendly;
    }

    public void setName(@NonNull String name) {
        if(name == null) {
            throw new NullPointerException("name");
        } else {
            this.name = name;
        }
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setFriendly(boolean friendly) {
        this.friendly = friendly;
    }

    private Person() {
    }

    private static TestClass.Person of() {
        return new TestClass.Person();
    }

    @ConstructorProperties({"name"})
    Person(@NonNull String name) {
        if(name == null) {
            throw new NullPointerException("name");
        } else {
            this.name = name;
        }
    }

    @ConstructorProperties({"name", "age", "friendly"})
    public Person(@NonNull String name, int age, boolean friendly) {
        if(name == null) {
            throw new NullPointerException("name");
        } else {
            this.name = name;
            this.age = age;
            this.friendly = friendly;
        }
    }
}

@Data:作用于類上,是以下注解的集合:@ToString @EqualsAndHashCode @Getter @Setter @RequiredArgsConstructor

@Builder:作用于類上砸王,將類轉(zhuǎn)變?yōu)榻ㄔ煺吣J?/p>

@Log:作用于類上推盛,生成日志變量。針對不同的日志實(shí)現(xiàn)產(chǎn)品谦铃,有不同的注解:

其他重要注解:

@Cleanup:自動(dòng)關(guān)閉資源耘成,針對實(shí)現(xiàn)了java.io.Closeable接口的對象有效,如:典型的IO流對象

編譯后結(jié)果如下:
是不是簡潔了太多。

@SneakyThrows:可以對受檢異常進(jìn)行捕捉并拋出瘪菌,可以改寫上述的main方法如下:

@Synchronized:作用于方法級別撒会,可以替換synchronize關(guān)鍵字或lock鎖,用處不大师妙。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诵肛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子默穴,更是在濱河造成了極大的恐慌怔檩,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蓄诽,死亡現(xiàn)場離奇詭異薛训,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)仑氛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門乙埃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锯岖,你說我怎么就攤上這事膊爪。” “怎么了嚎莉?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵米酬,是天一觀的道長。 經(jīng)常有香客問我趋箩,道長赃额,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任叫确,我火速辦了婚禮跳芳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘竹勉。我一直安慰自己飞盆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布次乓。 她就那樣靜靜地躺著吓歇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪票腰。 梳的紋絲不亂的頭發(fā)上城看,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天,我揣著相機(jī)與錄音杏慰,去河邊找鬼测柠。 笑死炼鞠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的轰胁。 我是一名探鬼主播谒主,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赃阀!你這毒婦竟也來了霎肯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凹耙,失蹤者是張志新(化名)和其女友劉穎姿现,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肖抱,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡备典,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了意述。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片提佣。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖荤崇,靈堂內(nèi)的尸體忽然破棺而出拌屏,到底是詐尸還是另有隱情,我是刑警寧澤术荤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布倚喂,位于F島的核電站,受9級特大地震影響瓣戚,放射性物質(zhì)發(fā)生泄漏端圈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一子库、第九天 我趴在偏房一處隱蔽的房頂上張望舱权。 院中可真熱鬧,春花似錦仑嗅、人聲如沸宴倍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鸵贬。三九已至,卻和暖如春浑彰,著一層夾襖步出監(jiān)牢的瞬間恭理,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工郭变, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颜价,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓诉濒,卻偏偏與公主長得像周伦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子未荒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 在面向?qū)ο缶幊讨斜夭豢缮傩枰诖a中定義對象模型专挪,而在基于Java的業(yè)務(wù)平臺開發(fā)實(shí)踐中尤其如此。相信大家在平時(shí)開發(fā)...
    消失er閱讀 12,738評論 15 150
  • 一片排、項(xiàng)目背景 在寫Java程序的時(shí)候經(jīng)常會(huì)遇到如下情形:新建了一個(gè)Class類寨腔,然后在其中設(shè)置了幾個(gè)字段,最后還需...
    西二旗老司機(jī)閱讀 904評論 0 1
  • 由于簡書2019年9月不可以發(fā)布新的博客捅僵,已經(jīng)把最新的博客發(fā)布到CSDN了家卖,文章鏈接Lombok簡介、使用庙楚、工作原...
    JourWon閱讀 51,200評論 0 32
  • 內(nèi)容概要 Lombok簡介 lombok是一個(gè)實(shí)用的第三方j(luò)ava工具上荡,可以通過簡單注解來精簡代碼達(dá)到消除冗長代碼...
    若兮緣閱讀 2,797評論 0 16
  • 1. lombok簡介 在寫Java程序的時(shí)候經(jīng)常會(huì)遇到如下情形:新建了一個(gè)Class類,然后在其中設(shè)置了幾個(gè)字段...
    wyatt_plus閱讀 20,272評論 4 5