簡介
JDK 14引入了記錄,這是一種新的類型聲明。像 enum
一樣,記錄是類的受限形式。它非常適合於純數據載體,即包含不打算更改的數據並且只包含最基本的方法(如構造函數和訪問函數)的類。
注意:這是一個預覽功能,它的設計、規範和實現都是完整的,但不是永久性的,這意味着該功能可能以不同的形式存在,或者在未來的JDK版本中根本不存在。若要編譯和運行包含預覽功能的代碼,必須指定其他命令行選項。
下面是一個普通的Java類:
final class FunTester {
final String name;
final int age;
public FunTester(String name, int age) {
this.name = name;
this.age = age;
}
public String name() {
return name;
}
public int age() {
return age;
}
}
它具有以下特點:
- 它的所有成員都被宣佈爲最終成員
- 它唯一的方法包括一個構造函數和兩個訪問屬性的方法
我們可以用一個record來替換這個類:
record FunTester(String name, int age) { }
record有以下幾個特點:
- 每個組件的私有
final
字段。 - 每個組件的公共讀訪問器方法,方法名與屬性名一致。
- 一個公共構造函數,其簽名從記錄組件列表中派生。
equals()
和hashCode()
方法的實現,如果兩個record對象屬於同一類型且其對應的記錄屬性相等,則指定這兩個記錄相等。toString()
方法的一個實現件的字符串表示及其名稱。
緊湊型構造函數
如果我們想記錄的構造函數不僅僅是初始化屬性值,那麼可以爲記錄定義一個自定義構造函數。然而,與類構造函數不同,記錄構造函數沒有正式的參數列表;這被稱爲緊湊構造函數。
例如,下面的record FunTester
,我們想在構造函數裏面校驗屬性值,可以用下面這種語法,雖然我們沒有顯式寫出賦值代碼,但是這些代碼實際是會生效。
record FunTester(String name, int age) {
public FunTester {
if (age < 0) {
throw new IllegalArgumentException("年齡不能爲負數");
}
Objects.requireNonNull(name, "名字不能爲空");
}
}
record的限制
以下是對record使用的限制:
- record不能擴展任何類
final
記錄不能聲明實例字段;任何其他聲明的字段必須是static
- record不能是抽象的;他們隱含地
final
- record的屬性是
final
的
除了這些限制之外,記錄的行爲與常規類相同。除此之外java.lang.Class有兩個與記錄相關的新方法:
- RecordComponent[] getRecordComponents():返回一個數組java.lang.reflect.RecordComponent對象,對應於記錄的組件。
- boolean isRecord():與此類似 ,只是如果類被聲明爲記錄則
isEnum()
返回。true
演示代碼如下:
public static void main(String[] args) {
FunTester fun = new FunTester("FunTester", 25);// 創建record對象
boolean record = fun.getClass().isRecord();// 判斷是否是record
System.out.println(record);// true
RecordComponent[] recordComponents = fun.getClass().getRecordComponents();// 獲取所有的組件
for (RecordComponent recordComponent : recordComponents) {
System.out.println(recordComponent.getName());// name, age
}
}