Java记录
https://openjdk.java.net/jeps/359概述了新的Java功能,該功能可能會/將在某些將來的Java版本中實現。 JEP建議使用一種新型的“班級”:記錄。 JEP中的示例內容如下:
record Range( int lo, int hi) { public Range { if (lo > hi) /* referring here to the implicit constructor parameters */ throw new IllegalArgumentException(String.format( "(%d,%d)" , lo, hi)); } }本質上,一條記錄將是一個類,該類只打算在構造函數中設置final字段。 到今天為止,JEP還允許類具有的任何其他成員,但從本質上說,記錄就是記錄,它是純數據,核心可能沒有功能。 記錄的描述簡短而切合實際,并且消除了很多我們需要用Java 13或更少的語言編碼此類或將要實現的版本記錄的樣板。 上面使用常規Java的代碼如下所示:
public class Range { final int lo; final int hi; public Range( int lo, int hi) { if (lo > hi) /* referring here to the implicit constructor parameters */ throw new IllegalArgumentException(String.format( "(%d,%d)" , lo, hi)); this .lo = lo; this .hi = hi; } }考慮到我的Java :: Geci代碼生成項目,這對于代碼生成器來說是一個巨大的挑戰,它彌合了當今與新功能在所有生產平臺上都可用的那一天之間的差距。
因此,我開始考慮如何開發此生成器,并且遇到了一些問題。 Java :: Geci框架只能將可編譯項目轉換為另一個可編譯項目。 它不能像將不完整的源代碼轉換為完整版本的其他代碼生成器那樣工作,該源代碼無法將不完整的源代碼(未經代碼生成器的修改就無法編譯)。 這是因為Java :: Geci在測試階段起作用。 為了進入測試階段,必須先編譯代碼。 這是一個眾所周知的折衷方案,是一項設計決策。 在大多數情況下,當Java :: Geci有用時,這很容易解決。 另一方面,我們得到的好處是生成器不需要配置管理,例如讀取和解釋屬性或XML文件。 它們僅提供API,并且從測試中調用它們的代碼通過它配置生成器。 最大的優點是,您甚至可以通過生成器調用的方法引用,lambda或對象實例的形式提供回調,以便這些生成器在其工作的某些方面可以具有完全開放的結構。
為什么在這種情況下如此重要? 記錄生成相當簡單,不需要任何復雜的配置,事實上,它根本不需要任何配置。 另一方面,可compilable -> compilable compilable -> compilable限制正在影響它。 如果您開始使用Java 8和Java :: Geci創建記錄,那么您的手動代碼將如下所示:
@Geci ( "record" ) public class Range { final int lo; final int hi; }這不會編譯,因為在代碼生成開始之前的第一次編譯時,默認構造函數不會初始化字段。 因此,這些字段不能為final :
@Geci ( "record" ) public class Range { int lo; int hi; }運行發電機,我們將得到
package javax0.geci.tests.record; import javax0.geci.annotations.Geci; @Geci ( "record" ) public final class Range { final int lo; final int hi; //<editor-fold id="record"> public Range( final int lo, final int hi) { this .lo = lo; this .hi = hi; } public int getLo() { return lo; } public int getHi() { return hi; } @Override public int hashCode() { return java.util.Objects.hash(lo, hi); } @Override public boolean equals(Object o) { if ( this == o) return true ; if (o == null || getClass() != o.getClass()) return false ; Range that = (Range) o; return java.util.Objects.equals(that.lo, lo) && java.util.Objects.equals(that.hi, hi); } //</editor-fold> }這個生成器實際上所做的是
- 它生成構造函數
- 將JEP的要求將類和字段轉換為final
- 生成字段的吸氣劑
- 為該類生成equals()和hashCode()方法
如果該類的void方法具有與該類相同的名稱(盡管不區分大小寫),例如:
public void Range( double hi, long lo) { if (lo > hi) /* referring here to the implicit constructor parameters */ throw new IllegalArgumentException(String.format( "(%d,%d)" , lo, hi)); }然后發電機將
- 從生成的構造函數中調用該方法,
- 修改方法的參數列表以匹配當前字段列表。
請注意,這種生成方法試圖表現出JEP中建議的最接近實際record的可能,并生成可立即轉換為新語法的代碼。 這就是驗證器方法必須與類具有相同名稱的原因。 當轉換為真實記錄時,所有要做的就是刪除將方法轉換為構造函數的void關鍵字,刪除參數列表,因為它將隱含在JEP中定義,并刪除編輯器折疊之間的所有生成代碼。 (也在首次執行生成器時自動生成)。
手動輸入的代碼的修改是Java :: Geci的新功能,它是由Record生成器的需求觸發的,旨在克服可compilable -> compilable的缺點compilable -> compilable compilable -> compilable限制。 后續文章中將詳細介紹Java 1.:Geci的下一個1.3.0版本中提供的生成器如何使用此功能。
帶走
本文的重點是,即使在Java記錄可用之前,也可以將其與Java 8、9一起使用。
翻譯自: https://www.javacodegeeks.com/2019/10/java-record.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
- 上一篇: linux设置时间命令(linux 设置
- 下一篇: javafx 调用java_Java验证