<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          讓人又愛又恨的 Lombok,到底該不該用

          共 9254字,需瀏覽 19分鐘

           ·

          2020-08-03 00:22

          點擊上方?果汁簡歷?,選擇“置頂公眾號”

          優(yōu)質(zhì)文章,第一時間送達

          這兩天關(guān)于 Lombok 的文章層出不窮,眾說紛紜,那么到底是該不該用呢?

          先說利好

          先說一下它可以做什么,最簡單的用法,幫助我們生成setter,gettertoStringequals 方法。如果我們不是用 Lombok 需要按照下面的方案寫什么內(nèi)容,我們也能看得出來這都是樣板代碼,沒啥實質(zhì)性

          import?java.util.Objects;

          public?class?User?{
          ????private?String?id;
          ????private?String?name;
          ????private?String?desc;

          ????public?String?getId()?{
          ????????return?id;
          ????}

          ????public?void?setId(String?id)?{
          ????????this.id?=?id;
          ????}

          ????public?String?getName()?{
          ????????return?name;
          ????}

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

          ????public?String?getDesc()?{
          ????????return?desc;
          ????}

          ????public?void?setDesc(String?desc)?{
          ????????this.desc?=?desc;
          ????}

          ????@Override
          ????public?String?toString()?{
          ????????return?"User{"?+
          ????????????????"id='"?+?id?+?'\''?+
          ????????????????",?name='"?+?name?+?'\''?+
          ????????????????",?desc='"?+?desc?+?'\''?+
          ????????????????'}';
          ????}

          ????@Override
          ????public?boolean?equals(Object?o)?{
          ????????if?(this?==?o)?return?true;
          ????????if?(o?==?null?||?getClass()?!=?o.getClass())?return?false;
          ????????User?user?=?(User)?o;
          ????????return?Objects.equals(id,?user.id)?&&
          ????????????????Objects.equals(name,?user.name)?&&
          ????????????????Objects.equals(desc,?user.desc);
          ????}

          ????@Override
          ????public?int?hashCode()?{
          ????????return?Objects.hash(id,?name,?desc);
          ????}
          }

          那么我們?nèi)绻褂?Lombok 呢?引入依賴

          <dependency>
          ??<groupId>org.projectlombokgroupId>
          ??<artifactId>lombokartifactId>
          ??<version>1.18.10version>
          ??<scope>providedscope>
          dependency>

          代碼

          import?lombok.Data;
          @Data
          public?class?User?{
          ????private?String?id;
          ????private?String?name;
          ????private?String?desc;
          }

          就這樣就寫好了,是不是非常簡單?Lombok還提供了很多其他擴展的注解能力如下

          • @NonNull:用于做空指針異常檢測;
          • @Cleanup:自動資源關(guān)閉,這個注解可以直接在流上面使用,@Cleanup InputStream inputStream = new FileInputStream();
          • @Getter/@Setter:自動生成get/set方法;
          • @ToString:生成toString方法,方便打印調(diào)試;
          • @EqualsAndHashCode:生成equals和hashCode方法,注意這兩個應(yīng)該同時去實現(xiàn);
          • @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor:構(gòu)造方法;
          • @Data:相當(dāng)于 @ToString + @EqualsAndHashCode + @Getter + @Setter + @RequiredArgsConstructor。
          • @Builder:生成builder方法;
          • @SneakyThrows:自動拋受檢異常,而無需顯式在方法上使用 throws 語句;
          • @Synchronized:用在方法上,將方法聲明為同步的,并自動加鎖。
          • @Log:日志相關(guān),如果我們打了@XSlf4j,任何 class 都可以直接使用 log變量獲取到日志對象實例。
          @CommonsLog:org.apache.commons.logging.LogFactory.getLog(LogExample.class);
          @Flogger:com.google.common.flogger.FluentLogger.forEnclosingClass();
          @JBossLog:org.jboss.logging.Logger.getLogger(LogExample.class);
          @Log:java.util.logging.Logger.getLogger(LogExample.class.getName());
          @Log4j:org.apache.log4j.Logger.getLogger(LogExample.class);
          @Log4j2:org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
          @Slf4j:org.slf4j.LoggerFactory.getLogger(LogExample.class);
          @XSlf4j:org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);
          @CustomLog:com.foo.your.LoggerFactory.createYourLogger(LogExample.class);

          下面是一些比較難理解的注解實例,直接可以通過注釋查看用法,后面附上了 IDEA 反編譯的 class 便一目了然。

          import?lombok.*;

          import?java.io.FileInputStream;
          import?java.io.InputStream;

          @Data
          @NoArgsConstructor
          @AllArgsConstructor
          @Builder
          public?class?User?{
          ????private?String?id;
          ????private?String?name;
          ????private?String?desc;

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

          ????????//?@NoArgsConstructor?生成
          ????????new?User();

          ????????//?@AllArgsConstructor?生成
          ????????new?User("juice-resume",?"果汁簡歷",?"專注于?Java?方向技術(shù)分享");

          ????????//?@Builder?生成
          ????????User?user?=?User.builder().id("juice-resume").name("果汁簡歷").desc("專注于?Java?方向技術(shù)分享").build();
          ????}

          ????//?@SneakyThrows?自動生成?throws?FileNotFoundException
          ????@SneakyThrows
          ????private?void?read()?{
          ????????//?@Cleanup?相當(dāng)于?inputStream.close();
          ????????@Cleanup
          ????????InputStream?inputStream?=?new?FileInputStream("");
          ????}

          ????/**
          ?????*?@Synchronized?private?final?Object?$lock?=?new?Object[0];
          ?????*?public?void?write()?{
          ?????*??????synchronized(this.$lock)?{
          ?????*??????????System.out.println("write");
          ?????*??????}
          ?????*?}
          ?????*/


          ????@Synchronized
          ????public?void?write()?{
          ????????System.out.println("write");
          ????}
          }

          IDEA 反編譯的 class 文件

          import?java.io.FileInputStream;
          import?java.io.InputStream;
          import?java.util.Collections;

          public?class?User?{
          ????private?final?Object?$lock?=?new?Object[0];
          ????private?String?id;
          ????private?String?name;
          ????private?String?desc;

          ????public?static?void?main(String[]?args)?{
          ????????new?User();
          ????????new?User("juice-resume",?"果汁簡歷",?"專注于?Java?方向技術(shù)分享");
          ????????User?user?=?builder().id("juice-resume").name("果汁簡歷").desc("專注于?Java?方向技術(shù)分享").build();
          ????}

          ????private?void?read()?{
          ????????try?{
          ????????????InputStream?inputStream?=?new?FileInputStream("");
          ????????????if?(Collections.singletonList(inputStream).get(0)?!=?null)?{
          ????????????????inputStream.close();
          ????????????}

          ????????}?catch?(Throwable?var2)?{
          ????????????throw?var2;
          ????????}
          ????}

          ????public?void?write()?{
          ????????synchronized(this.$lock)?{
          ????????????System.out.println("write");
          ????????}
          ????}

          ????public?static?User.UserBuilder?builder()?{
          ????????return?new?User.UserBuilder();
          ????}

          ????public?String?getId()?{
          ????????return?this.id;
          ????}

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

          ????public?String?getDesc()?{
          ????????return?this.desc;
          ????}

          ????public?void?setId(final?String?id)?{
          ????????this.id?=?id;
          ????}

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

          ????public?void?setDesc(final?String?desc)?{
          ????????this.desc?=?desc;
          ????}

          ????public?boolean?equals(final?Object?o)?{
          ????????if?(o?==?this)?{
          ????????????return?true;
          ????????}?else?if?(!(o?instanceof?User))?{
          ????????????return?false;
          ????????}?else?{
          ????????????User?other?=?(User)o;
          ????????????if?(!other.canEqual(this))?{
          ????????????????return?false;
          ????????????}?else?{
          ????????????????label47:?{
          ????????????????????Object?this$id?=?this.getId();
          ????????????????????Object?other$id?=?other.getId();
          ????????????????????if?(this$id?==?null)?{
          ????????????????????????if?(other$id?==?null)?{
          ????????????????????????????break?label47;
          ????????????????????????}
          ????????????????????}?else?if?(this$id.equals(other$id))?{
          ????????????????????????break?label47;
          ????????????????????}

          ????????????????????return?false;
          ????????????????}

          ????????????????Object?this$name?=?this.getName();
          ????????????????Object?other$name?=?other.getName();
          ????????????????if?(this$name?==?null)?{
          ????????????????????if?(other$name?!=?null)?{
          ????????????????????????return?false;
          ????????????????????}
          ????????????????}?else?if?(!this$name.equals(other$name))?{
          ????????????????????return?false;
          ????????????????}

          ????????????????Object?this$desc?=?this.getDesc();
          ????????????????Object?other$desc?=?other.getDesc();
          ????????????????if?(this$desc?==?null)?{
          ????????????????????if?(other$desc?!=?null)?{
          ????????????????????????return?false;
          ????????????????????}
          ????????????????}?else?if?(!this$desc.equals(other$desc))?{
          ????????????????????return?false;
          ????????????????}

          ????????????????return?true;
          ????????????}
          ????????}
          ????}

          ????protected?boolean?canEqual(final?Object?other)?{
          ????????return?other?instanceof?User;
          ????}

          ????public?int?hashCode()?{
          ????????int?PRIME?=?true;
          ????????int?result?=?1;
          ????????Object?$id?=?this.getId();
          ????????int?result?=?result?*?59?+?($id?==?null???43?:?$id.hashCode());
          ????????Object?$name?=?this.getName();
          ????????result?=?result?*?59?+?($name?==?null???43?:?$name.hashCode());
          ????????Object?$desc?=?this.getDesc();
          ????????result?=?result?*?59?+?($desc?==?null???43?:?$desc.hashCode());
          ????????return?result;
          ????}

          ????public?String?toString()?{
          ????????return?"User(id="?+?this.getId()?+?",?name="?+?this.getName()?+?",?desc="?+?this.getDesc()?+?")";
          ????}

          ????public?User()?{
          ????}

          ????public?User(final?String?id,?final?String?name,?final?String?desc)?{
          ????????this.id?=?id;
          ????????this.name?=?name;
          ????????this.desc?=?desc;
          ????}

          ????public?static?class?UserBuilder?{
          ????????private?String?id;
          ????????private?String?name;
          ????????private?String?desc;

          ????????UserBuilder()?{
          ????????}

          ????????public?User.UserBuilder?id(final?String?id)?{
          ????????????this.id?=?id;
          ????????????return?this;
          ????????}

          ????????public?User.UserBuilder?name(final?String?name)?{
          ????????????this.name?=?name;
          ????????????return?this;
          ????????}

          ????????public?User.UserBuilder?desc(final?String?desc)?{
          ????????????this.desc?=?desc;
          ????????????return?this;
          ????????}

          ????????public?User?build()?{
          ????????????return?new?User(this.id,?this.name,?this.desc);
          ????????}

          ????????public?String?toString()?{
          ????????????return?"User.UserBuilder(id="?+?this.id?+?",?name="?+?this.name?+?",?desc="?+?this.desc?+?")";
          ????????}
          ????}
          }

          好了,說了這么多該總結(jié)了,Lombok確實能給我們帶來極大的便利,減少大量重復(fù)、無業(yè)務(wù)邏輯的代碼,提高開發(fā)效率,那么它由什么缺點呢?更多IDEA相關(guān)技術(shù)可以關(guān)注微信訂閱號果汁簡歷回復(fù)IDEA獲取。

          再說弊端

          1. IDE 依賴

          上文中引入的 pom.xml 的依賴只是在 maven 編譯的時候有作用,如果使用 IDEA,本身也需要安裝插件,這樣對于新拉取代碼的同學(xué)無疑是一項額外的配置,當(dāng)然私以為就像是安裝 JDK 一樣,這個操作并不繁瑣。

          2. JDK版本兼容

          當(dāng)我想要將現(xiàn)有項目的JDK從Java 8升級到Java 11時,Lombok 會存在不兼容的問題,不過反過來講,這并不是一個致命問題,線上 run 的很好的項目,會那么輕易的就切換 JDK 版本么?如果是針對新的項目,自然有更多的選擇。JDK 并沒有萬不得已要升級的原因,如果真的有也可以用 Delombok 完成。

          3. 調(diào)試?yán)щy

          很多讀者反饋,因為沒有源碼 debug 困難,不過對于貧血模型來說,debug setter,gettertoStringequals 方法的機會也太少了吧,倘若你選擇的是充血模型,那么自然也不會選擇 Lombok了。

          孰輕孰重

          通看利弊以后我們發(fā)現(xiàn),好的地方很明顯,就是效率,同時也伴隨一些問題,但是倒不是不能接受,依賴、兼容、調(diào)試、可讀性其實相對于效率來說都略顯單薄,所以小編倒是推薦使用 Lombok,從效率角度出發(fā),把它僅僅當(dāng)做一個提效的工具,并不是爭相談?wù)摰脑掝}。當(dāng)然看下下面的圖, Lombok 既然能在 Top Downloads 位居第 6 名也不是刷出來的啦。

          1.?人人都能看懂的 6 種限流實現(xiàn)方案!

          2.?一個空格引發(fā)的“慘案“

          3.?大型網(wǎng)站架構(gòu)演化發(fā)展歷程

          4.?Java語言“坑爹”排行榜TOP 10

          5. 我是一個Java類(附帶精彩吐槽)

          6. 看完這篇Redis緩存三大問題,保你能和面試官互扯

          7. 程序員必知的 89 個操作系統(tǒng)核心概念

          8. 深入理解 MySQL:快速學(xué)會分析SQL執(zhí)行效率

          9. API 接口設(shè)計規(guī)范

          10. Spring Boot 面試,一個問題就干趴下了!



          掃碼二維碼關(guān)注我


          ·end·

          —如果本文有幫助,請分享到朋友圈吧—

          我們一起愉快的玩耍!



          你點的每個贊,我都認(rèn)真當(dāng)成了喜歡

          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产三级日韩三级欧美三级 | 色多多视频在线观看 | 欧美福利第一页 | 天天爱夜夜爽Av 婷婷99爱99热 | 无码野外|