Java 教程

Java 控制語句

面向物件程式設計

Java 內建類

Java 檔案處理

Java 錯誤和異常

Java 多執行緒

Java 同步

Java 網路程式設計

Java 集合

Java 介面

Java 資料結構

Java 集合演算法

高階 Java

Java 其他

Java APIs 和框架

Java 類引用

Java 有用資源

Java - 記錄



在 Java 14 中,一個令人興奮的特性 **record** 作為預覽特性被引入。**record** 特性有助於建立不可變資料物件。在 Java 15 版本中,**record 型別** 進行了進一步增強。在 Java 14 和 15 中,為了使用 **record**,必須傳遞標誌 --enable-preview。從 Java 16 開始,不需要此標誌,因為 **record** 是 JDK 的標準部分。

Java 記錄的目的

Java 記錄的主要目的是建立一個數據物件或 POJO,用於在應用程式程式流程中傳輸資料。在一個多層程式中,領域/模型物件儲存從資料來源捕獲的資料,然後這些模型物件被進一步傳遞到應用程式/UI 層以處理資料,反之亦然,UI/應用程式將資料儲存在資料物件中,然後將這些物件傳遞給資料層以填充資料來源。

由於這些資料物件包含許多欄位,開發人員需要編寫許多 setter/getter 方法、引數化建構函式、重寫的 equals 方法和 hashcode 方法。在這種情況下,record 派上用場,因為它提供了大部分樣板程式碼,開發人員只需關注所需的功能。

Java 記錄的特性

以下是使 record 成為一個令人興奮的特性的一些特性:

  • Record 物件具有一個隱式建構函式,所有引數都作為欄位變數
  • Record 物件對每個欄位變數都有隱式的欄位 getter 方法。
  • Record 物件對每個欄位變數都有隱式的欄位 setter 方法。
  • Record 物件具有隱式的、合理的 **hashCode()**、**equals()** 和 **toString()** 方法實現。
  • 在 Java 15 中,不能在記錄中宣告本地方法。
  • 在 Java 15 中,記錄的隱式欄位不是 final 的,使用反射修改會丟擲 IllegalAccessException。

不使用 Java 記錄的示例

讓我們建立一個不使用 record 的簡單程式,在這個程式中,我們建立了一個 Student 物件並列印其詳細資訊。Student 具有三個屬性:id、name 和 className。為了建立一個學生,我們建立了一個引數化建構函式、setter、getter 方法、equals 和 hashcode 方法。因此,我們的 Student 類包含近 60 多行程式碼。

package com.tutorialspoint;

public class Tester {
   public static void main(String args[]) {
      // create student objects
      Student student1 = new Student(1, "Mahesh", "XII");
      Student student2 = new Student(2, "Sudhir", "XII");

      // print the students
      System.out.println(student1);
      System.out.println(student2);

      // check if students are same
      boolean result = student1.equals(student2);
      System.out.println(result);

      // check if students are same
      result = student1.equals(student1);
      System.out.println(result);

      // get the hashcode
      System.out.println(student1.hashCode());
      System.out.println(student2.hashCode());
   }
}

class Student{
   private int id;
   private String name;
   private String className;

   Student(int id, String name, String className){
      this.id = id;
      this.name = name;
      this.className = className;
   }

   public int getId() {
      return id;
   }
   public void setId(int id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getClassName() {
      return className;
   }
   public void setClassName(String className) {
      this.className = className;
   }

   @Override
   public String toString() {
      return "Student[id: " + id + ", name: " + name 
         + ", class: " + className + "]";
   }

   @Override
   public boolean equals(Object obj) {
      if(obj == null || !(obj instanceof Student) ) {
         return false;
      }
      Student s = (Student)obj;

      return this.name.equals(s.name) 
         && this.id == s.id 
         && this.className.equals(s.className);
   }

   @Override
   public int hashCode() {
      int prime = 19;
      int result = 1;
      result = prime * result + ((name == null) ? 0 : name.hashCode());
      result = prime * result + ((className == null) ? 0 : className.hashCode());
      result = prime * result + id;
      return result;
   }  
}

讓我們編譯並執行上述程式,這將產生以下結果:

Student[id: 1, name: Mahesh, class: XII]
Student[id: 2, name: Sudhir, class: XII]
false
true
371251946
288252156

使用 Java 記錄的示例

讓我們使用 record 重新建立上述程式,在這個程式中,我們建立一個 Student 物件作為 record 並列印其詳細資訊。Student 具有三個屬性:id、name 和 className。在這裡你可以看到區別,完整的 Student 類被一行程式碼作為 Student record 所取代。

package com.tutorialspoint;

public class Tester {
   public static void main(String args[]) {
      // create student objects
      Student student1 = new Student(1, "Mahesh", "XII");
      Student student2 = new Student(2, "Sudhir", "XII");

      // print the students
      System.out.println(student1);
      System.out.println(student2);

      // check if students are same
      boolean result = student1.equals(student2);
      System.out.println(result);

      // check if students are same
      result = student1.equals(student1);
      System.out.println(result);

      // get the hashcode
      System.out.println(student1.hashCode());
      System.out.println(student2.hashCode());
   }
}

record Student(int id, String name, String className) {}

讓我們編譯並執行上述程式,這將產生以下結果:

Student[id: 1, name: Mahesh, class: XII]
Student[id: 2, name: Sudhir, class: XII]
false
true
371251946
288252156

我們也可以在記錄中新增自定義方法。但通常不需要。

用於密封介面的 Java 記錄

由於記錄預設情況下是最終的並且可以擴充套件介面,我們可以定義密封介面並讓記錄實現它們以更好地管理程式碼。

示例:密封介面的 Java 記錄用法

考慮以下示例:

package com.tutorialspoint;

public class Tester {
   public static void main(String[] args) {
      Person employee = new Employee(23, "Robert");
      System.out.println(employee.id());
	  System.out.println(employee.name());
   }
}
sealed interface Person permits Employee, Manager {
   int id();
   String name();
}
record Employee(int id, String name) implements Person {}
record Manager(int id, String name) implements Person {}

讓我們編譯並執行上述程式,這將產生以下結果:

23
Robert

覆蓋 Java 記錄的方法

我們可以輕鬆地覆蓋記錄方法實現並提供我們自己的實現。

示例:覆蓋 Java 記錄方法

考慮以下示例:

package com.tutorialspoint;

public class Tester {
   public static void main(String args[]) {
      // create student objects
      Student student = new Student(1, "Mahesh", "XII");

      System.out.println(student);
   }
}

record Student(int id, String name, String className) {
   public String toString() {
      return "Id: " + id + ", Name: " + name + ", class: " + className ;
   }
}

讓我們編譯並執行上述程式,這將產生以下結果:

Id: 1, Name: Mahesh, class: XII
廣告