Java?Record類介紹及使用方法詳解
簡介
Java Record類是Java 14引入的預(yù)覽特性,并在Java 16中正式成為標(biāo)準(zhǔn)功能,主要用于簡化不可變數(shù)據(jù)載體的創(chuàng)建,自動生成構(gòu)造方法、字段訪問器、equals()、hashCode()和toString()等方法。
Java Record類的核心特性
不可變性:所有字段默認(rèn)是final的,實例化后不可修改,適合表示純數(shù)據(jù)模型如DTO或值對象。
自動生成方法:編譯器自動生成全參數(shù)構(gòu)造器、字段訪問器(如name()而非getName())、equals()、hashCode()和toString()方法,顯著減少樣板代碼。
簡潔語法:與傳統(tǒng)類相比,Record類的聲明更簡潔。
例如:
public record Point(int x, int y) {}
等效于包含多個手動編寫方法的普通類。
與普通類的區(qū)別
繼承限制:Record類隱式繼承java.lang.Record,不能顯式繼承其他類,但可以實現(xiàn)接口。
字段限制:僅能定義頭部聲明的字段,不支持額外實例變量(靜態(tài)字段除外)。
默認(rèn)方法:自動生成規(guī)范方法,且不可重寫父類方法(因父類為Record)。
使用場景與最佳實踐
數(shù)據(jù)傳輸對象(DTO):簡化API請求/響應(yīng)的數(shù)據(jù)封裝。
不可變數(shù)據(jù)快照:如領(lǐng)域事件或配置參數(shù),確保數(shù)據(jù)一致性。
擴展功能:
通過緊湊構(gòu)造器實現(xiàn)參數(shù)校驗:
public record User(String name) {
public User { Objects.requireNonNull(name); }
}
添加自定義方法(如計算衍生屬性)。
jackson中的注解解釋
- @JsonProperty :此注解用于屬性上,作用是把該屬性的名稱序列化為另外一個名稱,如把trueName屬性序列化為name,@JsonProperty(“name”)。 對屬性名稱重命名,比如在很多場景下Java對象的屬性是按照規(guī)范的駝峰書寫,但在數(shù)據(jù)庫設(shè)計時使用的是下劃線連接方式,此處在進行映射的時候 就可以使用該注解。
- @JsonIgnore此注解用于屬性或者方法上(最好是屬性上),用來完全忽略被注解的字段和方法對應(yīng)的屬性,即便這個字段或方法可以被自動檢測到或者還有其 他的注解,一般標(biāo)記在屬性或者方法上,返回的json數(shù)據(jù)即不包含該屬性。
- @JsonIgnoreProperties此注解是類注解,作用是json序列化時將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方法上,用于在序列化時嵌入我們自定義的代碼,比如序列化一個double時在其后面限制兩位小數(shù)點。
- @JsonDeserialize此注解用于屬性或者setter方法上,用于在反序列化時可以嵌入我們自定義的代碼,類似于上面的@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": "會被忽略的值"
},
"anotherExtra": "也會被忽略"
}
@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)容請搜索腳本之家以前的文章或繼續(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)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
基于Springboot2.3訪問本地路徑下靜態(tài)資源的方法(解決報錯:Not allowed to load local
這篇文章主要介紹了基于Springboot2.3訪問本地路徑下靜態(tài)資源的方法(解決報錯:Not allowed to load local resource),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Java?將PDF轉(zhuǎn)為HTML時保存到流的方法和步驟
本文介紹如何通過Java后端程序代碼將PDF文件轉(zhuǎn)為HTML,并將轉(zhuǎn)換后的HTML文件保存到流,下面是實現(xiàn)轉(zhuǎn)換的方法和步驟,感興趣的朋友一起看看吧2022-01-01
Mybatis中l(wèi)ike搭配concat的寫法詳解
這篇文章主要介紹了Mybatis中l(wèi)ike搭配concat的寫法詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01
使用maven的profile構(gòu)建不同環(huán)境配置的方法
這篇文章主要介紹了使用maven的profile構(gòu)建不同環(huán)境配置的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
詳解如何把Java中if-else代碼重構(gòu)成高質(zhì)量代碼
這篇文章主要介紹了詳解如何把Java中if-else代碼重構(gòu)成高質(zhì)量代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

