Record類型
1、概念
記錄類型(record
)是JDK 14
的另一個預覽功能。記錄類型的作用類似於Kotlin
中的數據類(data class
)和Scala
中的case class
。記錄類型的作用是作爲不可變數據的封裝。類似於枚舉類型,記錄類型是一種形式受限的類。一個記錄類型由名稱和狀態描述兩部分組成。狀態描述聲明瞭記錄中包含的組件。
2、 示例
下面代碼中的Student
就是一個記錄類型。記錄類型使用record聲明。Student
記錄類型的狀態描述由id
和name
兩個Integer、String類型的組件組成。可以通過id()
和name()
方法來訪問。
/**
* Record的使用
*
* @author Leon
* @date 2020-04-13 8:47
*/
public class RecordDemo
{
public static void main(String[] args) {
Student stu = new Student(1001, "張三");
System.out.println(stu);
System.out.println(stu.getClass());
System.out.println(stu.id());
System.out.println(stu.name());
System.out.println("==============================");
Person p = new Person(1000, "李四", 22);
System.out.println(p);
System.out.println(p.getClass());
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getAge());
}
}
record Student(Integer id, String name){}
class Person
{
private Integer id;
private String name;
private Integer age;
public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
3、 深入理解
記錄類型有自動生成的成員有以下幾種:
- 狀態描述中的每個組件都有對應的private final字段。
- 狀態描述中的每個組件都有對應的public訪問方法。方法的名稱與組件名稱相同。
- 一個包含全部組件的公開構造器,用來初始化對應組件。
- 實現了equals()和hashCode()方法。equals()要求全部組件都必須相等。
- 實現了toString(),輸出全部組件的信息。
通過編譯軟件,查看Student的文件的內容如下:
final class Student extends java.lang.Record {
private final java.lang.Integer id;
private final java.lang.String name;
public Student(java.lang.Integer id, java.lang.String name) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public java.lang.Integer id() { /* compiled code */ }
public java.lang.String name() { /* compiled code */ }
}
從中我們可以得到如下一些關鍵信息。
- 記錄類型不能繼承自其它類
- 記錄類型不能有其他實例字段
- 記錄類型都是final的,也不能是abstract的
- 記錄中的字段也都是final的
如果需要在記錄類型的構造器中添加校驗或規格化的邏輯,可以定義自己的構造器。
注意
如果構造器不帶形式參數(類似下面代碼中的方式),則認爲是要覆寫默認生成的帶全部組件的構造器(即覆寫Student(Integer id, String name))。
record Student(Integer id, String name)
{
public Student
{
this.id = Math.abs(id);
this.name = name.strip();
}
}