Java?Record類(lèi)介紹及使用方法詳解
簡(jiǎn)介
Java Record類(lèi)是Java 14引入的預(yù)覽特性,并在Java 16中正式成為標(biāo)準(zhǔn)功能,主要用于簡(jiǎn)化不可變數(shù)據(jù)載體的創(chuàng)建,自動(dòng)生成構(gòu)造方法、字段訪問(wèn)器、equals()、hashCode()和toString()等方法。
Java Record類(lèi)的核心特性
不可變性:所有字段默認(rèn)是final的,實(shí)例化后不可修改,適合表示純數(shù)據(jù)模型如DTO或值對(duì)象。
自動(dòng)生成方法:編譯器自動(dòng)生成全參數(shù)構(gòu)造器、字段訪問(wèn)器(如name()而非getName())、equals()、hashCode()和toString()方法,顯著減少樣板代碼。
簡(jiǎn)潔語(yǔ)法:與傳統(tǒng)類(lèi)相比,Record類(lèi)的聲明更簡(jiǎn)潔。
例如:
public record Point(int x, int y) {}
等效于包含多個(gè)手動(dòng)編寫(xiě)方法的普通類(lèi)。
與普通類(lèi)的區(qū)別
繼承限制:Record類(lèi)隱式繼承java.lang.Record,不能顯式繼承其他類(lèi),但可以實(shí)現(xiàn)接口。
字段限制:僅能定義頭部聲明的字段,不支持額外實(shí)例變量(靜態(tài)字段除外)。
默認(rèn)方法:自動(dòng)生成規(guī)范方法,且不可重寫(xiě)父類(lèi)方法(因父類(lèi)為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ò)展功能:
通過(guò)緊湊構(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ū)寫(xiě),但在數(shù)據(jù)庫(kù)設(shè)計(jì)時(shí)使用的是下劃線連接方式,此處在進(jìn)行映射的時(shí)候 就可以使用該注解。
- @JsonIgnore此注解用于屬性或者方法上(最好是屬性上),用來(lái)完全忽略被注解的字段和方法對(duì)應(yīng)的屬性,即便這個(gè)字段或方法可以被自動(dòng)檢測(cè)到或者還有其 他的注解,一般標(biāo)記在屬性或者方法上,返回的json數(shù)據(jù)即不包含該屬性。
- @JsonIgnoreProperties此注解是類(lèi)注解,作用是json序列化時(shí)將java bean中的一些屬性忽略掉,序列化和反序列化都受影響。
- @JsonFormat此注解用于屬性或者方法上(最好是屬性上),可以方便的把Date類(lèi)型直接轉(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í)可以嵌入我們自定義的代碼,類(lèi)似于上面的@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類(lèi)介紹及使用方法的文章就介紹到這了,更多相關(guān)Java Record類(lèi)使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
try-with-resource優(yōu)雅關(guān)閉io流的方法
這篇文章主要給大家介紹了關(guān)于try-with-resource優(yōu)雅關(guān)閉io流的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
基于Springboot2.3訪問(wèn)本地路徑下靜態(tài)資源的方法(解決報(bào)錯(cuò):Not allowed to load local
這篇文章主要介紹了基于Springboot2.3訪問(wèn)本地路徑下靜態(tài)資源的方法(解決報(bào)錯(cuò):Not allowed to load local resource),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Java?將PDF轉(zhuǎn)為HTML時(shí)保存到流的方法和步驟
本文介紹如何通過(guò)Java后端程序代碼將PDF文件轉(zhuǎn)為HTML,并將轉(zhuǎn)換后的HTML文件保存到流,下面是實(shí)現(xiàn)轉(zhuǎn)換的方法和步驟,感興趣的朋友一起看看吧2022-01-01
SpringSecurity實(shí)現(xiàn)自定義登錄方式
本文介紹自定義登錄流程,包括自定義AuthenticationToken、AuthenticationFilter、AuthenticationProvider以及SecurityConfig配置類(lèi),詳細(xì)解析了認(rèn)證流程的實(shí)現(xiàn),為開(kāi)發(fā)人員提供了具體的實(shí)施指導(dǎo)和參考2024-09-09
Mybatis中l(wèi)ike搭配concat的寫(xiě)法詳解
這篇文章主要介紹了Mybatis中l(wèi)ike搭配concat的寫(xiě)法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
使用maven的profile構(gòu)建不同環(huán)境配置的方法
這篇文章主要介紹了使用maven的profile構(gòu)建不同環(huán)境配置的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
4個(gè)Java8中你需要知道的函數(shù)式接口分享
Java?8?中提供了許多函數(shù)式接口,包括Function、Consumer、Supplier、Predicate?等等。本文主要來(lái)和大家介紹一下它們的具體使用,需要的可以參考一下2023-04-04
詳解如何把Java中if-else代碼重構(gòu)成高質(zhì)量代碼
這篇文章主要介紹了詳解如何把Java中if-else代碼重構(gòu)成高質(zhì)量代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

