Java Record的使用場景分析
一、前言
- 學(xué)習(xí)新特性Record的作用
二、學(xué)習(xí)內(nèi)容:
- Record與Class的區(qū)別以及Record使用場景
三、問題描述
- 為什么引入Record以及Record的作用
四、解決方案:
4.1 為什么引入Record
Java 引入 record 的主要原因是為了簡化創(chuàng)建不可變數(shù)據(jù)類的過程,并提高代碼的可讀性和維護(hù)性。
以下是一些具體的原因:
減少樣板代碼:
- ?? record 自動(dòng)生成構(gòu)造器、equals()、hashCode() 和 toString() 方法,以及每個(gè)字段的 getter方法,這樣開發(fā)人員就可以專注于業(yè)務(wù)邏輯而不是樣板代碼。
不可變性:
- ?? record 的所有字段默認(rèn)是 final 的,這意味著它們是不可變的。這有助于創(chuàng)建線程安全和易于管理的數(shù)據(jù)模型。
簡潔性:
- record 允許你用更少的代碼來定義數(shù)據(jù)類,使得類的定義更加清晰和簡潔。
性能優(yōu)化:
- record 類型可能?? 受到編譯器的特定優(yōu)化,例如更有效的內(nèi)存布局,從而可能帶來性能上的提升。
模式匹配的支持:
- record 在模式匹配方面有更好的支持,這在 Java 14 及以后的版本中變得更加重要,尤其是在使用結(jié)構(gòu)化綁定和改進(jìn)的 switch
表達(dá)式時(shí)。
易于調(diào)試:
- 由于 record 自動(dòng)提供了 toString() 方法,因此在調(diào)試時(shí)可以更容易地查看對象的狀態(tài)。
明確的意圖:
- 使用 record 明確地表明了類的目的是作為一個(gè)簡單的數(shù)據(jù)載體,這對于其他開發(fā)人員閱讀代碼時(shí)是有幫助的。
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 自動(dòng)生成構(gòu)造器、equals()、hashCode() 和 toString() 方法,以及每個(gè)字段的 getter方法
我們運(yùn)行一下下面代碼看看區(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);
}
}結(jié)果如下:

4.3 語法與使用場景
適用于那些僅用于存儲(chǔ)數(shù)據(jù)而沒有復(fù)雜業(yè)務(wù)邏輯的情況
結(jié)構(gòu)體里面可擴(kuò)展內(nèi)容如下
??Record所有字段默認(rèn)是final
- 非靜態(tài)字段:
非靜態(tài)字段要通過構(gòu)造器(隱式final)去創(chuàng)建,不能在結(jié)構(gòu)體里面自定義- 你不能直接在 record 結(jié)構(gòu)體中手動(dòng)添加非 final 的字段。
- 如果你需要在結(jié)構(gòu)體自定義的字段,推薦使用 class。
// 構(gòu)造傳入
public record Person(String name, int age) {
// 這是合法的,因?yàn)樽侄卧诼暶髦卸x
// 不合法:不能再這里定義其他字段
// private final String address; // 這將導(dǎo)致編譯錯(cuò)誤
// 可以添加額外的方法
public String introduce() {
return String.format("My name is %s and I am %d years old.", name, age);
}
} - 實(shí)例方法:
- 除了 record 自動(dòng)生成的方法外,你可以添加自己的實(shí)例方法來擴(kuò)展 record 的功能。這些方法可以實(shí)現(xiàn)特定的業(yè)務(wù)邏輯或操作。
- 靜態(tài)成員:
- 你可以在 record 中添加靜態(tài)方法,這些方法通常用于工廠模式,即創(chuàng)建 record 實(shí)例的替代構(gòu)造方式。
- 可以添加靜態(tài)字段
- 可以添加靜態(tài)內(nè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)內(nè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);
}
}
// 實(shí)例方法
public String introduce() {
return name + " is " + age + " years old";
}
}
// 使用示例
public class Main {
public void example() {
// 使用靜態(tài)方法
Person defaultPerson = Person.createDefaultPerson();
// 使用靜態(tài)內(nèi)部類
Person customPerson = new Person.PersonBuilder()
.withName("John")
.build();
}
} - 私有方法:
- 私有方法可以用來封裝 record 內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),例如輔助計(jì)算或驗(yàn)證邏輯。
- 嵌套類和內(nèi)部類:
- record 可以包含嵌套類和內(nèi)部類,這些類可以用來定義相關(guān)的類型,比如枚舉類型或其他輔助類。
- 接口實(shí)現(xiàn):
- record 可以實(shí)現(xiàn)一個(gè)或多個(gè)接口,這樣就可以提供接口中定義的方法的實(shí)現(xiàn)。
- 注解:
- record 可以使用注解來標(biāo)記,這對于框架集成、元數(shù)據(jù)處理等非常有用。
- 泛型:
- record 支持泛型,允許你定義泛型參數(shù),從而創(chuàng)建通用的 record 類型。
- 覆蓋默認(rèn)方法:
- 盡管 record 自動(dòng)生成了一些方法,如 equals()、hashCode() 和toString(),你仍然可以覆蓋這些方法以提供不同的實(shí)現(xiàn)。
五、總結(jié):
5.1 場景使用
簡單的數(shù)據(jù)使用
?? 默認(rèn)只有Getter方法
record Point(int x, int y) {
// 無需顯式定義構(gòu)造器、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 記錄中,所有字段都必須在記錄的參數(shù)列表中定義。
?? 記錄是不可變的:字段一旦賦值,不能被修改。
?? 無法在記錄內(nèi)部定義額外的 private final 字段。
下面是相關(guān)解釋
隱式 final:
- 所有記錄字段默認(rèn)是 final,
這意味著它們一旦被初始化,就不能再被修改。
只能通過構(gòu)造器定義:
- 記錄中的字段必須在
記錄聲明的緊隨其后的參數(shù)列表中定義,不能在記錄的體內(nèi)再次定義或聲明。 - 這意味著
無法手動(dòng)添加如 private final 字段,直接在類體內(nèi)定義是非法的。
自動(dòng)構(gòu)造器和訪問器:
- Java 會(huì)為記錄自動(dòng)生成構(gòu)造器,以及每個(gè)字段的訪問器方法(getter)。因此,您不需要手動(dòng)編寫 getter 方法。
public record Person(String name, int age) {
// 這是合法的,因?yàn)樽侄卧诼暶髦卸x
// 不合法:不能再這里定義其他字段
// private final String address; // 這將導(dǎo)致編譯錯(cuò)誤
// 可以添加額外的方法
public String introduce() {
return String.format("My name is %s and I am %d years old.", name, age);
}
}
// 使用記錄的主函數(shù)
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ù)有遇到問題再添加)
到此這篇關(guān)于Java Record的使用 的文章就介紹到這了,更多相關(guān)java record使用 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java多線程抓取鈴聲多多官網(wǎng)的鈴聲數(shù)據(jù)
很容易就能發(fā)現(xiàn)通過改變 listId和page就能從服務(wù)器獲取鈴聲的json數(shù)據(jù), 通過解析json數(shù)據(jù), 可以看到都帶有{"hasmore":1,"curpage":1}這樣子的指示,通過判斷hasmore的值,決定是否進(jìn)行下一頁的抓取。 但是通過上面這個(gè)鏈接返回的json中不帶有鈴聲的下載地址2016-04-04
SpringBoot 中 AutoConfiguration的使用方法
這篇文章主要介紹了SpringBoot 中 AutoConfiguration的使用方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04

