Java Record的使用場景分析
一、前言
- 學習新特性Record的作用
二、學習內容:
- Record與Class的區(qū)別以及Record使用場景
三、問題描述
- 為什么引入Record以及Record的作用
四、解決方案:
4.1 為什么引入Record
Java 引入 record 的主要原因是為了簡化創(chuàng)建不可變數據類的過程,并提高代碼的可讀性和維護性。
以下是一些具體的原因:
減少樣板代碼:
- ?? record 自動生成構造器、equals()、hashCode() 和 toString() 方法,以及每個字段的 getter方法,這樣開發(fā)人員就可以專注于業(yè)務邏輯而不是樣板代碼。
不可變性:
- ?? record 的所有字段默認是 final 的,這意味著它們是不可變的。這有助于創(chuàng)建線程安全和易于管理的數據模型。
簡潔性:
- record 允許你用更少的代碼來定義數據類,使得類的定義更加清晰和簡潔。
性能優(yōu)化:
- record 類型可能?? 受到編譯器的特定優(yōu)化,例如更有效的內存布局,從而可能帶來性能上的提升。
模式匹配的支持:
- record 在模式匹配方面有更好的支持,這在 Java 14 及以后的版本中變得更加重要,尤其是在使用結構化綁定和改進的 switch
表達式時。
易于調試:
- 由于 record 自動提供了 toString() 方法,因此在調試時可以更容易地查看對象的狀態(tài)。
明確的意圖:
- 使用 record 明確地表明了類的目的是作為一個簡單的數據載體,這對于其他開發(fā)人員閱讀代碼時是有幫助的。
4.2 Record與Class區(qū)別
- 觀察下面Class代碼與Record代碼的區(qū)別
- Class
package org.example.recodes;
import java.util.Objects;
public class Cat {
String name;
public String getName() {
return name;
}
public Cat(String name) {
this.name = name;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Cat cat = (Cat) o;
return Objects.equals(name, cat.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}- Record
package org.example.recodes;
public record RecordCat(String name) { }?? 上面兩段代碼是等效的
record 自動生成構造器、equals()、hashCode() 和 toString() 方法,以及每個字段的 getter方法
我們運行一下下面代碼看看區(qū)別
package org.example.recodes;
public class Main {
public static void main(String[] args) {
Cat cat = new Cat("mimi");
System.out.println(cat.getName());
System.out.println(cat);
RecordCat recordCat = new RecordCat("momo");
System.out.println(recordCat.name());
System.out.println(recordCat);
}
}結果如下:

4.3 語法與使用場景
適用于那些僅用于存儲數據而沒有復雜業(yè)務邏輯的情況
結構體里面可擴展內容如下
??Record所有字段默認是final
- 非靜態(tài)字段:
非靜態(tài)字段要通過構造器(隱式final)去創(chuàng)建,不能在結構體里面自定義- 你不能直接在 record 結構體中手動添加非 final 的字段。
- 如果你需要在結構體自定義的字段,推薦使用 class。
// 構造傳入
public record Person(String name, int age) {
// 這是合法的,因為字段在聲明中定義
// 不合法:不能再這里定義其他字段
// private final String address; // 這將導致編譯錯誤
// 可以添加額外的方法
public String introduce() {
return String.format("My name is %s and I am %d years old.", name, age);
}
} - 實例方法:
- 除了 record 自動生成的方法外,你可以添加自己的實例方法來擴展 record 的功能。這些方法可以實現(xiàn)特定的業(yè)務邏輯或操作。
- 靜態(tài)成員:
- 你可以在 record 中添加靜態(tài)方法,這些方法通常用于工廠模式,即創(chuàng)建 record 實例的替代構造方式。
- 可以添加靜態(tài)字段
- 可以添加靜態(tài)內部類
public record Person(String name, int age) {
// 靜態(tài)字段
private static final String DEFAULT_COUNTRY = "Unknown";
// 靜態(tài)方法
public static Person createDefaultPerson() {
return new Person("Anonymous", 0);
}
// 靜態(tài)內部類
public static class PersonBuilder {
private String name;
private int age;
public PersonBuilder withName(String name) {
this.name = name;
return this;
}
public Person build() {
return new Person(name, age);
}
}
// 實例方法
public String introduce() {
return name + " is " + age + " years old";
}
}
// 使用示例
public class Main {
public void example() {
// 使用靜態(tài)方法
Person defaultPerson = Person.createDefaultPerson();
// 使用靜態(tài)內部類
Person customPerson = new Person.PersonBuilder()
.withName("John")
.build();
}
} - 私有方法:
- 私有方法可以用來封裝 record 內部的實現(xiàn)細節(jié),例如輔助計算或驗證邏輯。
- 嵌套類和內部類:
- record 可以包含嵌套類和內部類,這些類可以用來定義相關的類型,比如枚舉類型或其他輔助類。
- 接口實現(xiàn):
- record 可以實現(xiàn)一個或多個接口,這樣就可以提供接口中定義的方法的實現(xiàn)。
- 注解:
- record 可以使用注解來標記,這對于框架集成、元數據處理等非常有用。
- 泛型:
- record 支持泛型,允許你定義泛型參數,從而創(chuàng)建通用的 record 類型。
- 覆蓋默認方法:
- 盡管 record 自動生成了一些方法,如 equals()、hashCode() 和toString(),你仍然可以覆蓋這些方法以提供不同的實現(xiàn)。
五、總結:
5.1 場景使用
簡單的數據使用
?? 默認只有Getter方法
record Point(int x, int y) {
// 無需顯式定義構造器、equals()、hashCode() 或 toString()
}public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}5.2 字段的定義
?? 在 Java 記錄中,所有字段都必須在記錄的參數列表中定義。
?? 記錄是不可變的:字段一旦賦值,不能被修改。
?? 無法在記錄內部定義額外的 private final 字段。
下面是相關解釋
隱式 final:
- 所有記錄字段默認是 final,
這意味著它們一旦被初始化,就不能再被修改。
只能通過構造器定義:
- 記錄中的字段必須在
記錄聲明的緊隨其后的參數列表中定義,不能在記錄的體內再次定義或聲明。 - 這意味著
無法手動添加如 private final 字段,直接在類體內定義是非法的。
自動構造器和訪問器:
- Java 會為記錄自動生成構造器,以及每個字段的訪問器方法(getter)。因此,您不需要手動編寫 getter 方法。
public record Person(String name, int age) {
// 這是合法的,因為字段在聲明中定義
// 不合法:不能再這里定義其他字段
// private final String address; // 這將導致編譯錯誤
// 可以添加額外的方法
public String introduce() {
return String.format("My name is %s and I am %d years old.", name, age);
}
}
// 使用記錄的主函數
public class Main {
public static void main(String[] args) {
Person person = new Person("Alice", 30);
System.out.println(person.introduce()); // 輸出:My name is Alice and I am 30 years old.
}
}(后續(xù)有遇到問題再添加)
到此這篇關于Java Record的使用 的文章就介紹到這了,更多相關java record使用 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot 中 AutoConfiguration的使用方法
這篇文章主要介紹了SpringBoot 中 AutoConfiguration的使用方法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04

