Java 14的資料記錄將如何改變編碼方式:減少或消除對Lombok依賴 - oracle
在本文中將介紹Java中記錄的概念。記錄Record是Java類的一種新形式,旨在
- 提供對資料聚合建模的一流方法
- 彌補Java型別系統中的可能差距
- 提供通用程式設計模式的語言級語法
- 減少類樣板
什麼是Java記錄?
關於Java的最常見的抱怨之一是您需要編寫很多程式碼才能使一個類有用。通常,您需要編寫以下內容:
- toString()
- hashCode() 和 equals()
- Getter 方法
- 公開構造器
對於簡單的業務領域類,這些方法通常很無聊,重複,並且很容易機械生成(並且IDE通常提供此功能),但是到目前為止,語言本身還沒有提供任何方法來實現此目的。
當您閱讀別人的程式碼時,這種令人沮喪的差距實際上更加嚴重。例如,看起來作者使用的是IDE生成的,hashCode()並且equals()可以處理該類的所有欄位,但是如何確定不檢查實現的每一行呢?如果在重構過程中新增了欄位並且未重新生成方法,會發生什麼?
記錄的目的是擴充套件Java語言語法,並建立一種方式來表示類是“欄位,只是欄位,除了欄位之外什麼都沒有。”透過對類進行宣告,編譯器可以透過以下方式提供幫助:自動建立所有方法諸如hashCode(),在這些方法中使所有欄位有參與。
傳統Java類如下:
public final class FXOrderClassic { private final int units; private final CurrencyPair pair; private final Side side; private final double price; private final LocalDateTime sentAt; private final int ttl; public FXOrderClassic(int units, CurrencyPair pair, Side side, double price, LocalDateTime sentAt, int ttl) { this.units = units; this.pair = pair; // CurrencyPair is a simple enum this.side = side; // Side is a simple enum this.price = price; this.sentAt = sentAt; this.ttl = ttl; } public int units() { return units; } public CurrencyPair pair() { return pair; } public Side side() { return side; } public double price() { return price; } public LocalDateTime sentAt() { return sentAt; } public int ttl() { return ttl; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; FXOrderClassic that = (FXOrderClassic) o; if (units != that.units) return false; if (Double.compare(that.price, price) != 0) return false; if (ttl != that.ttl) return false; if (pair != that.pair) return false; if (side != that.side) return false; return sentAt != null ? sentAt.equals(that.sentAt) : that.sentAt == null; } @Override public int hashCode() { int result; long temp; result = units; result = 31 * result + (pair != null ? pair.hashCode() : 0); result = 31 * result + (side != null ? side.hashCode() : 0); temp = Double.doubleToLongBits(price); result = 31 * result + (int) (temp ^ (temp >>> 32)); result = 31 * result + (sentAt != null ? sentAt.hashCode() : 0); result = 31 * result + ttl; return result; } @Override public String toString() { return "FXOrderClassic{" + "units=" + units + ", pair=" + pair + ", side=" + side + ", price=" + price + ", sentAt=" + sentAt + ", ttl=" + ttl + '}'; } } |
提供了用於宣告記錄的簡潔語法,其中程式設計師所需要做的就是宣告組成記錄的元件名稱和型別,如下所示:
public record FXOrder(int units, CurrencyPair pair, Side side, double price, LocalDateTime sentAt, int ttl) {} |
FXOrder型別就是提供的最終狀態,它的任何例項都是欄位值的透明聚合。
要訪問新的語言功能,您需要使用Preview標誌編譯任何宣告記錄的程式碼:
javac --enable-preview -source 14 FXOrder.java |
如果使用javap來檢查,可以看到編譯器已自動生成了一堆樣板程式碼。(在下面的反編譯中,我僅顯示方法及其簽名。)
$ javap FXOrder.class Compiled from "FXOrder.java" public final class FXOrder extends java.lang.Record { public FXOrder(int, CurrencyPair, Side, double, java.time.LocalDateTime, int); public java.lang.String toString(); public final int hashCode(); public final boolean equals(java.lang.Object); public int units(); public CurrencyPair pair(); public Side side(); public double price(); public java.time.LocalDateTime sentAt(); public int ttl(); } |
這看起來非常類似於之前基於類的實現的傳統程式碼中的方法集。實際上,建構函式和訪問器方法的行為均與以前完全相同。
記錄是一種特殊的類形式,它以最小的語法實現了資料載體模式。您期望的所有樣板程式碼都將由編譯器自動生成。
緊湊的建構函式
您可能想驗證訂單以確保它們不嘗試買賣負數量或設定無效的TTL值:
public record FXOrder(int units, CurrencyPair pair, Side side, double price, LocalDateTime sentAt, int ttl) { public FXOrder { if (units < 1) { throw new IllegalArgumentException( "FXOrder units must be positive"); } if (ttl < 0) { throw new IllegalArgumentException( "FXOrder TTL must be positive, or 0 for market orders"); } if (price <= 0.0) { throw new IllegalArgumentException( "FXOrder price must be positive"); } } } |
緊湊的建構函式不會導致編譯器生成單獨的建構函式。而是,您在緊湊型建構函式中指定的程式碼將在規範建構函式的開頭顯示為額外的程式碼。您無需為欄位指定建構函式引數的分配,該分配仍會自動生成並以通常的方式出現在建構函式中。
與其他語言中的匿名元組相比,Java記錄具有的一個優勢是,記錄的建構函式主體允許在建立記錄時執行程式碼。這樣可以進行驗證(如果透過了無效狀態,則丟擲異常)。在純結構元組中這是不可能的。
總結
記錄旨在成為簡單的資料載體,這是元組的一種版本,以邏輯上一致的方式適合Java的已建立型別系統。這將幫助許多應用程式使域類更清晰,更小。它還將幫助團隊消除對底層模式的許多手工編碼實現,並減少或消除對Lombok之類的庫的需求。
但是,就像密封型別一樣,將來會出現一些最重要的記錄用例。模式匹配,尤其是允許將記錄分解成其各個組成部分的解構模式,顯示了巨大的希望,並且很可能會改變許多開發人員使用Java進行程式設計的方式。密封型別和記錄的組合還為Java提供了一種稱為代數資料型別的語言功能。
如果您熟悉其他程式語言中的這些功能,那就太好了。如果沒有,請不要擔心。它們被設計為適合您已經知道的Java語言,並且易於在您的程式碼中開始使用。
但是,您必須始終記住,在交付包含特定語言功能的Java最終版本之前,您不應依賴它。正如我在本文中所討論的那樣,當談論可能的未來功能時,應始終理解,僅出於探索目的而討論該功能。
以上為摘錄,完整文章點選標題見原文
相關文章
- 主動學習可減少對標註資料的依賴卻會造成標註冗餘?
- Kubernetes 將改變資料庫的管理方式資料庫
- 從今天開始,學習Webpack,減少對腳手架的依賴(下)Web
- 從今天開始,學習Webpack,減少對腳手架的依賴(上)Web
- 人工智慧將如何改變資料安全人工智慧
- linux 改變GCC編譯器的位元組對齊方式LinuxGC編譯
- 實時渲染將如何改變工作方式
- 物聯網將如何改變我們的思維方式
- [譯]JavaScript的新功能將改變正規表示式的編寫方式JavaScript
- Spring的依賴注入的方式Spring依賴注入
- win10如何改變資料夾下所有影片的播放方式Win10
- pytest 用例資料依賴如何處理
- win10如何改變資料夾下所有視訊的播放方式Win10
- 記錄遇到的一個迴圈依賴問題
- 記錄一次模型 依賴注入 踩過的坑: 控制器方法依賴注入模型變數名與路由變數名必須相同模型依賴注入變數路由
- 減少運維工作量,如何透過 ROS 輕鬆實現資源編排新方式運維ROS
- 如何用最簡單的方式解釋依賴注入?依賴注入是如何實現解耦的?(通俗易懂)依賴注入解耦
- 記錄Jackson和Lombok的坑Lombok
- Spring的三種依賴注入的方式Spring依賴注入
- Java面試題:讓依賴注入變得簡單,面對@Autowired和@Resource,該如何選擇?Java面試題依賴注入
- 歷時大半年,Github團隊成功減少30kb依賴體積Github
- YouGov:1/5的千禧一代為減少對地球的影響改變了飲食Go
- 使用Java 14的新記錄型別連線資料庫表 - MinborgJava型別資料庫
- 區塊鏈技術將如何改變個人資料安全區塊鏈
- 如何將python配置的依賴包以及版本匯出Python
- Builder設計模式結合lombok減少過多傳參UI設計模式Lombok
- Node工程的依賴包管理方式
- spring常用的三種依賴注入方式Spring依賴注入
- 依賴注入?依賴注入是如何實現解耦的?依賴注入解耦
- 如何解決微服務之間的資料依賴問題?微服務
- 面試官:你是如何理解Java中依賴倒置和依賴注入以及控制反轉的?面試Java依賴注入
- 高效的資料壓縮編碼方式 Protobuf
- 依賴反向傳播改進神經網路資料處理的精確度反向傳播神經網路
- 自動化將改變工作性質的5種方式
- 微服務之間的資料依賴問題,該如何解決?微服務
- Java依賴版本衝突Java
- 中國對AI的投資是如何加速改變世界的?AI
- 疫情如何改變我們的資料中心運營、管理方式?