Java21之字符串模板的使用小結(jié)
字符串模板是很多語(yǔ)言都具備的特性,它允許在字符串中使用占位符來(lái)動(dòng)態(tài)替換變量的值,這種構(gòu)建字符串的方式比傳統(tǒng)的字符串拼接或格式化更為簡(jiǎn)潔和直觀。相信學(xué)過(guò) JavaScript 的同學(xué)對(duì)下面這個(gè) Template literals 的語(yǔ)法不陌生:
const name = 'zhangsan'
const age = 18
const message = `My name is ${name}, I'm ${age} years old.`
console.log(message)
如上所示,JavaScript 通過(guò)反引號(hào) ` 來(lái)定義字符串模板,而 Java 21 則引入了一個(gè)叫做 模版表達(dá)式(Template expressions) 的概念來(lái)定義字符串模板。下面是一個(gè)簡(jiǎn)單示例:
String name = "zhangsan";
int age = 18;
String message = STR."My name is \{name}, I'm \{age} years old.";
System.out.println(message);
看上去和 JavaScript 的 Template literals 非常相似,但還是有一些區(qū)別的,模版表達(dá)式包含三個(gè)部分:
- 首先是一個(gè) 模版處理器(template processor):這里使用的是
STR模板處理器,也可以是RAW或FMT等,甚至可以自定義; - 中間是一個(gè)點(diǎn)號(hào)(
.); - 最后跟著一個(gè)字符串模板,模板中使用
\{name}和\{age}這樣的占位符語(yǔ)法,這被稱為 內(nèi)嵌表達(dá)式(embedded expression);
當(dāng)模版表達(dá)式運(yùn)行的時(shí)候,模版處理器會(huì)將模版內(nèi)容與內(nèi)嵌表達(dá)式的值組合起來(lái),生成結(jié)果。
不過(guò),當(dāng)我們執(zhí)行上述代碼時(shí),很可能會(huì)報(bào) Invalid escape sequence (valid ones are \b \t \n \f \r \" \' \\ ) 這樣的錯(cuò):

這是因?yàn)樽址0暹€只是一個(gè)預(yù)覽特性,根據(jù) JEP 12: Preview Features,我們需要添加 --enable-preview 參數(shù)開(kāi)啟預(yù)覽特性,使用 javac 編譯時(shí),還需要添加 --release 參數(shù)。使用下面的命令將 .java 文件編譯成 .class 文件:
$ javac --enable-preview --release 21 StringTemplates.java Note: StringTemplates.java uses preview features of Java SE 21. Note: Recompile with -Xlint:preview for details.
再使用下面的命令運(yùn)行 .class 文件:
$ java --enable-preview StringTemplates My name is zhangsan, I'm 18 years old.
從 Java 11 開(kāi)始,我們可以直接運(yùn)行 .java 文件了,參見(jiàn) JEP 330,所以上面的兩個(gè)命令也可以省略成一個(gè)命令:
$ java --enable-preview --source 21 StringTemplates.java
STR模版處理器
STR 模板處理器中的內(nèi)嵌表達(dá)式還有很多其他寫法,比如執(zhí)行數(shù)學(xué)運(yùn)算:
int x = 1, y = 2;
String s1 = STR."\{x} + \{y} = \{x + y}";
調(diào)用方法:
String s2 = STR."Java version is \{getVersion()}";
訪問(wèn)字段:
Person p = new Person(name, age);
String s3 = STR."My name is \{p.name}, I'm \{p.age} years old.";
內(nèi)嵌表達(dá)式中可以直接使用雙引號(hào),不用 \" 轉(zhuǎn)義:
String s4 = STR."I'm \{age >= 18 ? "an adult" : "a child"}.";
內(nèi)嵌表達(dá)式中可以編寫注釋和換行:
String s5 = STR."I'm \{
// check the age
age >= 18 ? "an adult" : "a child"
}.";
多行模板表達(dá)式
在 Java 13 的 JEP 355 中首次引入了 文本塊(Text Blocks) 特性,并經(jīng)過(guò) Java 14 的 JEP 368 和 Java 15 的 JEP 378 兩個(gè)版本的迭代,使得該特性正式可用,這個(gè)特性可以讓我們?cè)?Java 代碼中愉快地使用多行字符串。在使用文本塊之前,定義一個(gè) JSON 格式的字符串可能會(huì)寫出像下面這樣無(wú)法直視的代碼來(lái):
String json1 = "{\n" +
" \"name\": \"zhangsan\",\n" +
" \"age\": 18\n" +
"}\n";
但是在使用文本塊之后,這樣的代碼就變得非常清爽:
String json2 = """
{
"name": "zhangsan",
"age": 18
}
""";
文本塊以三個(gè)雙引號(hào) """ 開(kāi)始,同樣以三個(gè)雙引號(hào)結(jié)束,看上去和 Python 的多行字符串類似,不過(guò) Java 的文本塊會(huì)自動(dòng)處理?yè)Q行和縮進(jìn),使用起來(lái)更方便。上面的文本塊在 Java 中輸出如下:
{
"name": "zhangsan",
"age": 18
}注意開(kāi)頭沒(méi)有換行,結(jié)尾有一個(gè)換行。而在 Python 中輸出如下:
{
"name": "zhangsan",
"age": 18
}不僅開(kāi)頭和結(jié)尾都有換行,而且每一行有很多縮進(jìn),這里可以看出 Python 的處理很簡(jiǎn)單,它直接把 """ 之間的內(nèi)容原樣輸出了,而 Java 是根據(jù)最后一個(gè) """ 和內(nèi)容之間的相對(duì)縮進(jìn)來(lái)決定輸出。很顯然,我們更喜歡 Java 這樣的輸出結(jié)果,如果希望 Python 有同樣的輸出結(jié)果,就得這樣寫:
json = """{
"name": "zhangsan",
"age": 18
}
"""
這在代碼的可讀性上就比不上 Java 了,這里不得不感嘆 Java 的設(shè)計(jì),在細(xì)節(jié)的處理上做的確實(shí)不錯(cuò)。
言歸正傳,說(shuō)回字符串模板這個(gè)特性,我們也可以在文本塊中使用,如下:
String json3 = STR."""
{
"name": "\{name}",
"age": \{age}
}
""";
FMT模板處理器
FMT 是 Java 21 內(nèi)置的另一個(gè)模版處理器,它不僅有 STR 模版處理器的插值功能,還可以對(duì)輸出進(jìn)行格式化操作。格式說(shuō)明符(format specifiers) 放在嵌入表達(dá)式的左側(cè),如下所示:
%7.2f\{price}
支持的格式說(shuō)明符參見(jiàn) java.util.Formatter 文檔。
不過(guò)在我的環(huán)境里編譯時(shí),會(huì)報(bào)錯(cuò) cannot find symbol: variable FMT,就算是把鏡像更換成 openjdk:22-jdk 也是一樣的錯(cuò),不清楚是為什么。
小結(jié)
我們今天學(xué)習(xí)了 Java 21 引入的 字符串模板(String Templates) 特性,它通過(guò) 模板表達(dá)式 和 內(nèi)嵌表達(dá)式 的設(shè)計(jì),使得字符串的構(gòu)造更加簡(jiǎn)潔、直觀和類型安全。字符串模板的核心優(yōu)勢(shì)在于:
- 簡(jiǎn)潔性:相比傳統(tǒng)的字符串拼接或
String.format()等方法,模板表達(dá)式的寫法更加簡(jiǎn)潔易讀,特別是在處理復(fù)雜的多行字符串時(shí),結(jié)合文本塊特性,代碼的可讀性得到了顯著提升; - 靈活的模板處理器:Java 21 內(nèi)置了
STR和FMT兩個(gè)模板處理器,滿足不同的需求,同時(shí)開(kāi)發(fā)者也可以實(shí)現(xiàn)自定義的模板處理器來(lái)擴(kuò)展功能; - 與文本塊的完美配合:字符串模板與文本塊特性搭配使用,在處理 JSON、XML、HTML 等多行格式化文本時(shí),表現(xiàn)出了顯著的優(yōu)勢(shì),使代碼變得更加優(yōu)雅;
總的來(lái)說(shuō),字符串模板是 Java 語(yǔ)言在現(xiàn)代化演進(jìn)中的又一個(gè)重要步伐,通過(guò)借鑒其他編程語(yǔ)言(如 JavaScript、Python、Kotlin 等)的成功經(jīng)驗(yàn),為 Java 開(kāi)發(fā)者提供了更加便利和舒適的開(kāi)發(fā)體驗(yàn)。
到此這篇關(guān)于Java21之字符串模板的使用小結(jié)的文章就介紹到這了,更多相關(guān)Java21 字符串模板內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 2021最新Java?JDK1.8的安裝超詳細(xì)教程
- IDEA報(bào)錯(cuò):java:無(wú)效的源發(fā)行版21解決方式
- 你應(yīng)該知道的21個(gè)Java核心技術(shù)
- 2022年最新java?8?(?jdk1.8u321)安裝圖文教程
- idea創(chuàng)建spring?boot項(xiàng)目時(shí)javaversion只能選擇17和21解決辦法
- IDEA中JDK是1.8但Java版本只有21和17的解決辦法
- 利用Java快速查找21位花朵數(shù)示例代碼
- 解決idea創(chuàng)建版本時(shí)只有Java21和Java17選項(xiàng)
- IntelliJ IDEA 2021.1 EAP 1 發(fā)布支持 Java 16 和 WSL 2
相關(guān)文章
MyBatis-Plus攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限控制的方法
MyBatis-Plus是一款基于MyBatis的增強(qiáng)工具,它提供了一些便捷的功能和增強(qiáng)的查詢能力,數(shù)據(jù)權(quán)限控制是在系統(tǒng)中對(duì)用戶訪問(wèn)數(shù)據(jù)進(jìn)行限制的一種機(jī)制,這篇文章主要給大家介紹了關(guān)于MyBatis-Plus攔截器實(shí)現(xiàn)數(shù)據(jù)權(quán)限控制的相關(guān)資料,需要的朋友可以參考下2024-01-01
Java爬蟲Jsoup+httpclient獲取動(dòng)態(tài)生成的數(shù)據(jù)
這篇文章主要介紹了Java爬蟲Jsoup+httpclient獲取動(dòng)態(tài)生成的數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2017-05-05
用Java實(shí)現(xiàn)一個(gè)靜態(tài)鏈表的方法步驟
這篇文章主要介紹了用Java實(shí)現(xiàn)一個(gè)靜態(tài)鏈表的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
Java中將一個(gè)列表拆分為多個(gè)較小列表的三種不同方法
有時(shí)候我們需要將大集合按指定的數(shù)量分割成若干個(gè)小集合,這篇文章主要給大家介紹了關(guān)于Java中將一個(gè)列表拆分為多個(gè)較小列表的三種不同方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09
Java基于LoadingCache實(shí)現(xiàn)本地緩存的示例代碼
本文主要介紹了Java基于LoadingCache實(shí)現(xiàn)本地緩存的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Redisson分布式鎖實(shí)現(xiàn)原理示例詳解
Redisson分布式鎖通過(guò)Lua腳本保證原子性操作,實(shí)現(xiàn)了分布式互斥、可重入、自動(dòng)續(xù)期等核心特性,其高級(jí)特性包括公平鎖、讀寫鎖和紅鎖算法,能夠滿足不同場(chǎng)景下的并發(fā)控制需求,這篇文章主要介紹了Redisson分布式鎖實(shí)現(xiàn)原理的相關(guān)資料,需要的朋友可以參考下2026-04-04
Spring boot動(dòng)態(tài)修改日志級(jí)別的方法
我們經(jīng)常會(huì)遇到業(yè)務(wù)想看debug日志的問(wèn)題,但是debug日志頻繁打印會(huì)對(duì)日志查看有影響,且日志多對(duì)系統(tǒng)也會(huì)有一定的壓力,因此,如果可以在需要的時(shí)候動(dòng)態(tài)臨時(shí)調(diào)整下日志的級(jí)別則是比較完美的,spring boot已經(jīng)支持這種功能,需要的朋友可以參考下2022-12-12

