Java 14 發布了,可以扔掉Lombok了?

2020-12-15 計算機java編程

2020年3月17日發布,Java正式發布了JDK 14 ,目前已經可以開放下載。在JDK 14中,共有16個新特性,本文主要來介紹其中的一個特性:JEP 359: Records

官方吐槽最為致命

早在2019年2月份,Java 語言架構師 Brian Goetz,曾經寫過一篇文章,詳盡的說明了並吐槽了Java語言,他和很多程式設計師一樣抱怨「Java太囉嗦」或有太多的「繁文縟節」,他提到:開發人員想要創建純數據載體類(plain data carriers)通常都必須編寫大量低價值、重複的、容易出錯的代碼。如:構造函數、getter/setter、equals()、hashCode()以及toString()等。

以至於很多人選擇使用IDE的功能來自動生成這些代碼。還有一些開發會選擇使用一些第三方類庫,如Lombok等來生成這些方法,從而會導致了令人吃驚的表現(surprising behavior)和糟糕的可調試性(poor debuggability)。

那麼,Brian Goetz 大神提到的純數據載體到底指的是什麼呢。他舉了一個簡單的例子:

這裡面的Piont其實就是一個純數據載體,他表示一個"點"中包含x坐標和y坐標,並且只提供了構造函數,以及一些equals、hashCode等方法。

於是,BrianGoetz大神提出一種想法,他提到,Java完全可以對於這種純數據載體通過另外一種方式表示。

其實在其他的面向對象語言中,早就針對這種純數據載體有單獨的定義了,如Scala中的case、Kotlin中的data以及C#中的record。這些定義,儘管在語義上有所不同,但是它們的共同點是類的部分或全部狀態可以直接在類頭中描述,並且這個類中只包含了純數據而已。

於是,他提出Java中是不是也可以通過如下方式定義一個純數據載體呢?

record Point(int x, int y){ }

神說要用record,於是就有了

就像大神吐槽的那樣,我們通常需要編寫大量代碼才能使類變得有用。如以下內容:

toString()方法hashCode() and equals()方法Getter 方法一個共有的構造函數對於這種簡單的類,這些方法通常是無聊的、重複的,而且是可以很容易地機械地生成的那種東西(ide通常提供這種功能)。

當你閱讀別人的代碼時,可能會更加頭大。例如,別人可能使用IDE生成的hashCode()和equals()來處理類的所有欄位,但是如何才能在不檢查實現的每一行的情況下確定他寫的對呢?如果在重構過程中添加了欄位而沒有重新生成方法,會發生什麼情況呢?

大神Brian Goetz提出了使用record定義一個純數據載體的想法,於是,Java 14 中便包含了一個新特性:EP 359: Records ,作者正是 Brian Goetz

Records的目標是擴展Java語言語法,Records為聲明類提供了一種緊湊的語法,用於創建一種類中是「欄位,只是欄位,除了欄位什麼都沒有」的類。通過對類做這樣的聲明,編譯器可以通過自動創建所有方法並讓所有欄位參與hashCode()等方法。這是JDK 14中的一個預覽特性。

一言不合反編譯

Records的用法比較簡單,和定義Java類一樣:

record Person (String firstName, String lastName) {}

如上,我們定義了一個Person記錄,其中包含兩個組件:firstName和lastName,以及一個空的類體。

那麼,這個東西看上去也是個語法糖,那他到底是怎麼實現的那?

我們先嘗試對他進行編譯,記得使用

--enable-preview

參數,因為records功能目前在JDK 14中還是一個預覽(preview)功能。

如前所述,Record只是一個類,其目的是保存和公開數據。讓我們看看用javap進行反編譯,將會得到以下代碼:

通過反編譯得到的類,我們可以得到以下信息:

1、生成了一個final類型的Person類(class),說明這個類不能再有子類了。

2、這個類繼承了java.lang.Record類,這個我們使用enum創建出來的枚舉都默認繼承java.lang.Enum有點類似

3、類中有兩個private final 類型的屬性。所以,record定義的類中的屬性都應該是private final類型的。

4、有一個public的構造函數,入參就是兩個主要的屬性。如果通過字節碼查看其方法體的話,其內容就是以下代碼,你一定很熟悉:

5、有兩個getter方法,分別叫做firstName和lastName。這和JavaBean中定義的命名方式有區別,或許大神想通過這種方式告訴我們record定義出來的並不是一個JavaBean吧。

6、還幫我們自動生成了toString(), hashCode() 和 equals()方法。值得一提的是,這三個方法依賴invokedynamic來動態調用包含隱式實現的適當方法。

還可以這樣玩

前面的例子中,我們簡單的創建了一個record,那麼,record中還能有其他的成員變量和方法嗎?我們來看下。

1、我們不能將實例欄位添加到record中。但是,我們可以添加靜態欄位。

2、我們可以定義靜態方法和實例方法,可以操作對象的狀態。

3、我們還可以添加構造函數。

所以,我們是可以在record中添加靜態欄位/方法的,但是問題是,我們應該這麼做嗎?

請記住,record推出背後的目標是使開發人員能夠將相關欄位作為單個不可變數據項組合在一起,而不需要編寫冗長的代碼。這意味著,每當您想要向您的記錄添加更多的欄位/方法時,請考慮是否應該使用完整的類來代替它。

總結

record 解決了使用類作為數據包裝器的一個常見問題。純數據類從幾行代碼顯著地簡化為一行代碼。

但是,record目前是一種預覽語言特性,這意味著,儘管它已經完全實現,但在JDK中還沒有標準化。

那麼問題來了,如果你用上了Java 14之後,你還會使用Lombok嗎?哦不,你可能短時間內都用不上,因為你可能Java 8都還沒用熟~

相關焦點

  • Lombok使用指南
    >在 build.gradle 文件中添加 Lombok 依賴:dependencies { compileOnly 'org.projectlombok:lombok:1.18.10' annotationProcessor 'org.projectlombok:lombok:1.18.10'}Ant
  • 你不得不會的Lombok全面詳細講解,全網最詳細的教程
    lombok的官方地址:https://projectlombok.org/lombok的Github地址:https://github.com/rzwitserloot/lombokLombok plugin 插件Intellij idea 使用Lombok需要安裝插件
  • 優雅的代碼,高效的開發,Lombok來搞定
    尊敬的讀者,記得加關注、點讚喲,您的認可是我最大的動力,謝謝Lombok是一個Java庫,可以自動將某些代碼插入編輯器並構建的工具,為您的java增添色彩,不用再寫一個getter或equals方法,使用一個注釋,您的類就能具有一個功能齊全的構建器
  • 擁有眾多迷妹的Lombok了解一下
    Eclipse的Lombok插件安裝可以自行百度,也比較簡單,值得一提的是,由於Eclipse內置的編譯器不是Oracle javac,而是eclipse自己實現的Eclipse Compiler for Java (ECJ).要讓ECJ支持Lombok,需要在eclipse.ini配置文件中添加如下兩項內容:-Xbootclasspath/a:[lombok.jar
  • 一份不可多得的 Lombok 學習指南
    :lombok:1.18.10' annotationProcessor 'org.projectlombok:lombok:1.18.10'}    在 Maven 項目的 pom.xml 文件中添加 Lombok 依賴:   org.projectlombokgroupId> lombokartifactId
  • 迷茫了,我們到底該不該用lombok?
    前言最近上網查資料發現很多人對lombok褒貶不一,引起了我的興趣,因為我們項目中也在大量使用lombok,大家不同的觀點讓我也困惑了幾天,今天結合我實際的項目經驗,說說我的個人建議。隨便搜搜就找到了這幾篇文章:這些人建議使用 lombok,覺得它是一個神器,可以大大提高編碼效率,並且讓代碼更優雅。
  • Lombok的@Builder不好使?來試試這個
    以下文章來源於苦味代碼 ,作者L相信Lombok插件大家一定不會陌生,一個常用的註解是:@Builer, 它可以幫我們快速實現一個builder模式。試試SuperBuilder吧這個問題在lombokv1.18.2版本之前其實很難辦,但是在這個版本官方引入了一個新的註解@SuperBuilder,無法build父類的問題迎刃而解The @SuperBuilder annotation produces complex builder APIs for your classes.
  • IntelliJ IDEA 2020.2.1 發布,Lombok 插件可能被官方支持
    前言IntelliJ IDEA 2020.2.1 發布了,更新內容如下:修復了 Lombok 插件被異常阻止的問題經調試後,MacBook Touch Bar 不再卡住改進了 Gradle 和項目視圖中的文件選擇快捷方式恢復正常IDE 將顯示 WSL 文件系統上項目的本地歷史記錄現在可以在 Windows 上打開在驅動器根目錄中創建的項目IDE 可以平穩地運行資料庫查詢
  • 小辣椒神器Lombok
    </groupId> <artifactId>lombok</artifactId> <version>1.18.6</version>
  • IntelliJ IDEA安裝和開啟lombok
    簡述lombok是開源的代碼生成庫,是一款非常實用的小工具,lombok可以使實體類減少getter、setter等方法的編寫,在更改實體類時只需要修改屬性即可,減少了很多重複代碼的編寫工作。原料IntelliJ IDEA2020.01.01lombok安裝
  • Intellij IDEA 安裝lombok及使用方法
    lombok是一個可以通過簡單的註解的形式來幫助我們簡化消除一些必須有但顯得很臃腫的 Java 代碼的工具,在我們項目開發中經常使用model,entity等類,絕大部分數據類類中都需要get、set、toString等方法,一般我們需要手動的添加這些屬性, 但是如果我們受到業務的變更
  • 記一次使用 Lombok 造成的事故!
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫序言去年在項目當中引入了Lombok插件,著實解放了雙手,代替了一些重複的簡單工作(Getter,Setter,toString等方法的編寫
  • Java 拷貝,你能說出個 123 麼?
    Java 基本複製方法java賦值是複製對象引用,如果我們想要得到一個對象的==副本==,使用賦值操作是無法達到目的的:修改新對象的值會同時修改舊對象的值。,而互不影響,就需要用到java中對象的複製,如原生的clone()方法。
  • Java新特性:數據類型可以扔掉了?
    所以使用 enum 關鍵字定義常量,儘管從 Java 語法上看起來與使用 class 關鍵字定義類、使用 interface 關鍵字定義接口是同一層次的,但實際上這是由 Javac 編譯器做出來的假象,從字節碼的角度來看,枚舉僅僅是一個繼承於 java.lang.Enum、自動生成了 values() 和 valueOf() 方法的普通 Java 類而已,因此枚舉也歸為引用類型了。
  • 支持Java 14!Java 開發工具 IntelliJ IDEA 2020.1 穩定版發布
    這是今年發布的首個重大更新版本,新版本增加了對 Java 14 的支持、為部分 Web 和測試框架添加新功能、為調試器添加數據流分析協助功能(dataflow analysis assistance)、新增 LightEdit 模式,以及支持從 IDE 下載和配置 JDK。
  • Lombok,你的開發效率神器!
    ->Plugins,然後搜索 Lombok 安裝即可;安裝後提示重啟 IDE 即可;在需要使用的項目中加入 Lombok 編譯支持,pom 文件中加入以下依賴;<dependency><groupId>org.projectlombok
  • Lombok 看這篇就夠了
    也可以減少一些 get/set/toString 方法的編寫,雖說 IDEA 的插件可以自動生成 get/set/toString 方法,但是使用 Lombok 可以讓代碼更簡潔。下面看看如何在 IDEA中如何安裝 Lombok:安裝打開 IDEA 的 Settings 面板,並選擇 Plugins 選項,然後點擊 「Browse repositories」在輸入框輸入」lombok」,得到搜索結果,點擊安裝,然後安裝提示重啟 IDEA,安裝成功;
  • 給Java新手的一些建議——Java知識點歸納(Java基礎部分)
    JVM作為java運行的基礎,很難相信對於JVM一點都不了解的人可以把java語言吃得很透。我在面試有超過3年Java經驗的開發者的時候, JVM幾乎就是一個必問的問題了。當然JVM不是唯一決定技術能力好壞的面試問題,但是可以佐證java開發能力的高低。
  • 新手學Java編程應該學那些Java基礎知識
    自己總結的一些java基礎知識,想入行java的跟新手都可以看看!  經過這麼多年的Java開發,以及結合平時面試Java開發者的一些經驗,我覺得對於J2SE方面主要就是要掌握以下的一些內容。  1.