Java?Record類介紹及使用方法詳解
簡(jiǎn)介
Java Record類是Java 14引入的預(yù)覽特性,并在Java 16中正式成為標(biāo)準(zhǔn)功能,主要用于簡(jiǎn)化不可變數(shù)據(jù)載體的創(chuàng)建,自動(dòng)生成構(gòu)造方法、字段訪問器、equals()、hashCode()和toString()等方法。
Java Record類的核心特性
不可變性:所有字段默認(rèn)是final的,實(shí)例化后不可修改,適合表示純數(shù)據(jù)模型如DTO或值對(duì)象。
自動(dòng)生成方法:編譯器自動(dòng)生成全參數(shù)構(gòu)造器、字段訪問器(如name()而非getName())、equals()、hashCode()和toString()方法,顯著減少樣板代碼。
簡(jiǎn)潔語(yǔ)法:與傳統(tǒng)類相比,Record類的聲明更簡(jiǎn)潔。
例如:
public record Point(int x, int y) {}
等效于包含多個(gè)手動(dòng)編寫方法的普通類。
與普通類的區(qū)別
繼承限制:Record類隱式繼承java.lang.Record,不能顯式繼承其他類,但可以實(shí)現(xiàn)接口。
字段限制:僅能定義頭部聲明的字段,不支持額外實(shí)例變量(靜態(tài)字段除外)。
默認(rèn)方法:自動(dòng)生成規(guī)范方法,且不可重寫父類方法(因父類為Record)。
使用場(chǎng)景與最佳實(shí)踐
數(shù)據(jù)傳輸對(duì)象(DTO):簡(jiǎn)化API請(qǐng)求/響應(yīng)的數(shù)據(jù)封裝。
不可變數(shù)據(jù)快照:如領(lǐng)域事件或配置參數(shù),確保數(shù)據(jù)一致性。
擴(kuò)展功能:
通過緊湊構(gòu)造器實(shí)現(xiàn)參數(shù)校驗(yàn):
public record User(String name) {
public User { Objects.requireNonNull(name); }
}
添加自定義方法(如計(jì)算衍生屬性)。
jackson中的注解解釋
- @JsonProperty :此注解用于屬性上,作用是把該屬性的名稱序列化為另外一個(gè)名稱,如把trueName屬性序列化為name,@JsonProperty(“name”)。 對(duì)屬性名稱重命名,比如在很多場(chǎng)景下Java對(duì)象的屬性是按照規(guī)范的駝峰書寫,但在數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí)使用的是下劃線連接方式,此處在進(jìn)行映射的時(shí)候 就可以使用該注解。
- @JsonIgnore此注解用于屬性或者方法上(最好是屬性上),用來完全忽略被注解的字段和方法對(duì)應(yīng)的屬性,即便這個(gè)字段或方法可以被自動(dòng)檢測(cè)到或者還有其 他的注解,一般標(biāo)記在屬性或者方法上,返回的json數(shù)據(jù)即不包含該屬性。
- @JsonIgnoreProperties此注解是類注解,作用是json序列化時(shí)將java bean中的一些屬性忽略掉,序列化和反序列化都受影響。
- @JsonFormat此注解用于屬性或者方法上(最好是屬性上),可以方便的把Date類型直接轉(zhuǎn)化為我們想要的模式。 例子:@JsonFormat(pattern=“yyyy-MM-dd hh:mm:ss”) @JsonFormat(pattern=“yyyy-MM-dd HH:mm:ss”) private Date updateTime;
- @JsonSerialize此注解用于屬性或者getter方法上,用于在序列化時(shí)嵌入我們自定義的代碼,比如序列化一個(gè)double時(shí)在其后面限制兩位小數(shù)點(diǎn)。
- @JsonDeserialize此注解用于屬性或者setter方法上,用于在反序列化時(shí)可以嵌入我們自定義的代碼,類似于上面的@JsonSerialize。
- @JsonInclude 屬性值為null的不參與序列化。例子:@JsonInclude(Include.NON_NULL)
代碼示例
@Service
public class WeatherService {
private static final String BASE_URL = "https://api.weather.gov";
private final RestClient restClient;
public WeatherService() {
this.restClient = RestClient.builder()
.baseUrl(BASE_URL)
.defaultHeader("Accept", "application/geo+json")
.defaultHeader("User-Agent", "WeatherApiClient/1.0 (your@email.com)")
.build();
}
@JsonIgnoreProperties(ignoreUnknown = true)
public record Points(@JsonProperty("properties") Props properties) {
@JsonIgnoreProperties(ignoreUnknown = true)
public record Props(@JsonProperty("forecast") String forecast) {
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public record Forecast(@JsonProperty("properties") Props properties) {
@JsonIgnoreProperties(ignoreUnknown = true)
public record Props(@JsonProperty("periods") List<Period> periods) {
}
@JsonIgnoreProperties(ignoreUnknown = true)
public record Period(@JsonProperty("number") Integer number, @JsonProperty("name") String name,
@JsonProperty("startTime") String startTime, @JsonProperty("endTime") String endTime,
@JsonProperty("isDaytime") Boolean isDayTime, @JsonProperty("temperature") Integer temperature,
@JsonProperty("temperatureUnit") String temperatureUnit,
@JsonProperty("temperatureTrend") String temperatureTrend,
@JsonProperty("probabilityOfPrecipitation") Map probabilityOfPrecipitation,
@JsonProperty("windSpeed") String windSpeed, @JsonProperty("windDirection") String windDirection,
@JsonProperty("icon") String icon, @JsonProperty("shortForecast") String shortForecast,
@JsonProperty("detailedForecast") String detailedForecast) {
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public record Alert(@JsonProperty("features") List<Feature> features) {
@JsonIgnoreProperties(ignoreUnknown = true)
public record Feature(@JsonProperty("properties") Properties properties) {
}
@JsonIgnoreProperties(ignoreUnknown = true)
public record Properties(@JsonProperty("event") String event, @JsonProperty("areaDesc") String areaDesc,
@JsonProperty("severity") String severity, @JsonProperty("description") String description,
@JsonProperty("instruction") String instruction) {
}
}
/**
* Get forecast for a specific latitude/longitude
* @param latitude Latitude
* @param longitude Longitude
* @return The forecast for the given location
* @throws RestClientException if the request fails
*/
@Tool(description = "Get weather forecast for a specific latitude/longitude")
public String getWeatherForecastByLocation(double latitude, double longitude) {
var points = restClient.get()
.uri("/points/{latitude},{longitude}", latitude, longitude)
.retrieve()
.body(Points.class);
var forecast = restClient.get().uri(points.properties().forecast()).retrieve().body(Forecast.class);
String forecastText = forecast.properties().periods().stream().map(p -> {
return String.format("""
%s:
Temperature: %s %s
Wind: %s %s
Forecast: %s
""", p.name(), p.temperature(), p.temperatureUnit(), p.windSpeed(), p.windDirection(),
p.detailedForecast());
}).collect(Collectors.joining());
return forecastText;
}
/**
* Get alerts for a specific area
* @param state Area code. Two-letter US state code (e.g. CA, NY)
* @return Human readable alert information
* @throws RestClientException if the request fails
*/
@Tool(description = "Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY)")
public String getAlerts(@ToolParam( description = "Two-letter US state code (e.g. CA, NY") String state) {
Alert alert = restClient.get().uri("/alerts/active/area/{state}", state).retrieve().body(Alert.class);
return alert.features()
.stream()
.map(f -> String.format("""
Event: %s
Area: %s
Severity: %s
Description: %s
Instructions: %s
""", f.properties().event(), f.properties.areaDesc(), f.properties.severity(),
f.properties.description(), f.properties.instruction()))
.collect(Collectors.joining("\n"));
}
public static void main(String[] args) {
WeatherService client = new WeatherService();
System.out.println(client.getWeatherForecastByLocation(47.6062, -122.3321));
System.out.println(client.getAlerts("NY"));
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public record Points(@JsonProperty("properties") Props properties) {
@JsonIgnoreProperties(ignoreUnknown = true)
public record Props(@JsonProperty("forecast") String forecast) {
}
}
相當(dāng)于下面結(jié)構(gòu)
Points:{
"properties": {
"forecast": "晴天",
"extraField": "會(huì)被忽略的值"
},
"anotherExtra": "也會(huì)被忽略"
}
@JsonIgnoreProperties(ignoreUnknown = true)
public record Forecast(@JsonProperty("properties") Props properties) {
@JsonIgnoreProperties(ignoreUnknown = true)
public record Props(@JsonProperty("periods") List<Period> periods) {
}
@JsonIgnoreProperties(ignoreUnknown = true)
public record Period(@JsonProperty("number") Integer number, @JsonProperty("name") String name,
@JsonProperty("startTime") String startTime, @JsonProperty("endTime") String endTime,
@JsonProperty("isDaytime") Boolean isDayTime, @JsonProperty("temperature") Integer temperature,
@JsonProperty("temperatureUnit") String temperatureUnit,
@JsonProperty("temperatureTrend") String temperatureTrend,
@JsonProperty("probabilityOfPrecipitation") Map probabilityOfPrecipitation,
@JsonProperty("windSpeed") String windSpeed, @JsonProperty("windDirection") String windDirection,
@JsonProperty("icon") String icon, @JsonProperty("shortForecast") String shortForecast,
@JsonProperty("detailedForecast") String detailedForecast) {
}
}
相當(dāng)于下面的結(jié)構(gòu):
{
"properties": {
"periods": [
{
"number": 1,
"name": "Tonight",
"startTime": "2023-11-01T18:00:00-05:00",
"endTime": "2023-11-02T06:00:00-05:00",
"isDaytime": false,
"temperature": 45,
"temperatureUnit": "F",
"temperatureTrend": "rising",
"probabilityOfPrecipitation": {
"value": 20,
"unit": "percent"
},
"windSpeed": "5 to 10 mph",
"windDirection": "SW",
"icon": "https://api.weather.gov/icons/land/night/few?size=medium",
"shortForecast": "Partly Cloudy",
"detailedForecast": "Partly cloudy, with a low around 45. Southwest wind 5 to 10 mph."
},
{
"number": 2,
"name": "Wednesday",
"startTime": "2023-11-02T06:00:00-05:00",
"endTime": "2023-11-02T18:00:00-05:00",
"isDaytime": true,
"temperature": 72,
"temperatureUnit": "F",
"temperatureTrend": null,
"probabilityOfPrecipitation": {
"value": 0,
"unit": "percent"
},
"windSpeed": "10 mph",
"windDirection": "W",
"icon": "https://api.weather.gov/icons/land/day/skc?size=medium",
"shortForecast": "Sunny",
"detailedForecast": "Sunny, with a high near 72. West wind around 10 mph."
}
]
}
}
總結(jié)
到此這篇關(guān)于Java Record類介紹及使用方法的文章就介紹到這了,更多相關(guān)Java Record類使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
elasticsearch集群cluster主要功能詳細(xì)分析
這篇文章主要為大家介紹了elasticsearch集群cluster主要功能詳細(xì)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
MyBatis參數(shù)綁定中參數(shù)名不一致導(dǎo)致的錯(cuò)誤問題解決方法
作為一名Java開發(fā)者,我在實(shí)際項(xiàng)目中曾多次遇到MyBatis參數(shù)綁定的問題,其中最常見的一種情況是MyBatis參數(shù)綁定中參數(shù)名不一致導(dǎo)致的錯(cuò)誤,這類問題看似簡(jiǎn)單,但若不深入理解MyBatis的參數(shù)綁定機(jī)制,極易陷入誤區(qū),本文將帶大家一起探討解決方案,需要的朋友可以參考下2025-06-06
Spring Cloud Eureka 服務(wù)上下線監(jiān)控的實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud Eureka 服務(wù)上下線監(jiān)控的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09
Java操作Jenkins操作憑證(Credential)信息方式
這篇文章主要介紹了Java操作Jenkins操作憑證(Credential)信息方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05
使用jd-gui反編譯修改jar包里的.class并重新生成新jar問題
這篇文章主要介紹了使用jd-gui反編譯修改jar包里的.class并重新生成新jar問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
使用Java實(shí)現(xiàn)通用樹形結(jié)構(gòu)構(gòu)建工具類
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)通用樹形結(jié)構(gòu)構(gòu)建工具類,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-03-03

