Java 21 中的字串模板
一、簡介
在本教程中,我們將討論 Java 對字串插值的回答—字串模板。此預發布預覽功能是作為 Java 21 和JEP 430的一部分引入的。
2. Java中的字串組合
我們使用Strings
來表示數字、字母和符號的序列來表示程式碼中的文字。 Strings
在程式設計中無所不在,我們經常需要組合字串以在程式碼中使用。有多種方法可以做到這一點,每種技術都有其缺點。
2.1.字串連接
字串連接是我們用來建構字串的最基本操作。我們採用字串文字和表達式,然後使用+
符號將它們組合在一起:
String composeUsingPlus(String feelsLike, String temperature, String unit){
return "Today's weather is " + feelsLike +
", with a temperature of " + temperature + " degrees " + unit;
}
該程式碼實現了所需的功能,但難以閱讀,尤其是帶有所有加號,並且也難以維護和更改。
2.2. StringBuffer
或StringBuilder
我們可以使用Java提供的實用程式類,例如StringBuilder
和StringBuffer
類。這些類別為我們提供了append()
庫函數來組合字串,從而消除了字串組合中+
的使用:
String composeUsingStringBuilder(String feelsLike, String temperature, String unit) {
return new StringBuilder()
.append("Today's weather is ")
.append(feelsLike)
.append(", with a temperature of ")
.append(temperature)
.append(" degrees ")
.append(unit)
.toString();
}
StringBuilder
和StringBuffer
類別提供高效率的字串操作和組合技術,同時減少記憶體開銷。然而,它們遵循Builder
設計模式,因此變得相當冗長。
2.3.字串格式化程式
Java 為我們提供了使用String.format()
或formatted()
方法分離 String 的靜態部分和參數的能力,例如temperature
和unit
:
String composeUsingFormatters(String feelsLike, String temperature, String unit) {
return String.format("Today's weather is %s, with a temperature of %s degrees %s",
feelsLike, temperature, unit);
}
基本模板字串保持靜態。然而,此處傳遞的參數的順序和數量對於其響應的正確性至關重要。
2.4. MessageFormat
類
Java 提供了Java.text
套件的MessageFormat
類,可協助使用動態資料的佔位符組合文字訊息。在Localisation
和Internationalisation
大量使用了這一點。我們可以在純字串組合中使用MessageFormat.format()
:
String composeUsingMessageFormatter(String feelsLike, String temperature, String unit) {
return MessageFormat.format("Today''s weather is {0}, with a temperature of {1} degrees {2}",
feelsLike, temperature, unit);
}
這也有與上述類似的缺點。此外,語法結構與我們在程式碼中編寫和使用字串的方式不同。
3. 字串範本簡介
正如我們所看到的,上面提到的所有字串組合技術都有其缺點。讓我們看看字串模板如何幫助解決這些問題。
3.1.目標
將字串模板引入 Java 程式生態系統是為了實現以下目標:
- 使用可在運行時編譯的值簡化表達
Strings
的過程 - 增強
String
組合的可讀性,克服與StringBuilder
和StringBuffer
類別相關的冗長內容 - 克服了其他程式語言允許的
String
插值技術的安全問題,權衡了少量的不便 - 允許 Java 函式庫定義產生的字串文字的自訂格式語法
3.2.模板表達式
字串模板最重要的概念圍繞著模板表達式,這是 Java 中一種新型的可程式化表達式。可編程模板表達式可以執行插值,但也為我們提供了安全有效地組合字串的靈活性。
模板表達式可以將結構化文字轉換為任何對象,而不僅限於字串。
模板表達式由三個組成部分組成:
- 一個處理器
- 包含嵌入表達式的資料的模板
- 點 (.) 字符
4. 模板處理器
模板處理器負責評估嵌入的表達式(模板),並在運行時將其與String
文字組合以產生最終的String
。 Java 提供了使用 Java 提供的內建模板處理器或使用我們自己的自訂處理器進行切換的能力。
這是 Java 21 中的預覽功能;因此,我們必須啟用預覽模式。
4.1. STR
模板處理器
Java 提供了一些開箱即用的模板處理器。 STR
模板處理器透過迭代地將所提供模板的每個嵌入表達式替換為該表達式的字串化值來執行字串插值。我們將在前面的範例中應用STR
處理器字串模板:
String interpolationUsingSTRProcessor(String feelsLike, String temperature, String unit) {
return STR
. "Today's weather is \{ feelsLike }, with a temperature of \{ temperature } degrees \{ unit }" ;
}
STR
是一個公用靜態最終字段,會自動匯入到每個 Java 編譯單元。
我們不僅可以將上述實作擴展到單行字串,還可以擴展到多行表達式。對於多行文字區塊,我們用“””
包圍文字區塊。讓我們以插入表示 JSON 的字串為例:
String interpolationOfJSONBlock(String feelsLike, String temperature, String unit) {
return STR
. """
{
"feelsLike": "\{ feelsLike }",
"temperature": "\{ temperature }",
"unit": "\{ unit }"
}
""" ;
}
我們也可以內聯注入表達式,它將在執行時間編譯:
String interpolationWithExpressions() {
return STR
. "Today's weather is \{ getFeelsLike() }, with a temperature of \{ getTemperature() } degrees \{ getUnit() }";
}
4.2. FMT
模板處理器
Java 提供的另一個處理器是FMT
模板處理器。它添加了對提供給處理器的理解格式化程序的支持,並根據提供的格式化樣式格式化資料。
提供的formatter
應該類似於java.util.Formatter:
String interpolationOfJSONBlockWithFMT(String feelsLike, float temperature, String unit) {
return FMT
. """
{
"feelsLike": "%1s\{ feelsLike }",
"temperature": "%2.2f\{ temperature }",
"unit": "%1s\{ unit }"
}
""" ;
}
這裡,我們使用%s
和%f
將字串和溫度格式化為特定格式。
4.3.模板表達式的求值
該行中模板表達式的計算涉及幾個步驟:
STR
. "Today's weather is \{ feelsLike }, with a temperature of \{ temperature } degrees \{ unit }" ;
上面是我們將看到的幾個步驟的簡寫。
首先,透過評估點的左側獲得模板處理器的實例StringTemplate.Processor<R, E>
。在我們的範例中,它是STR
模板處理器。
接下來,我們透過計算點的右邊來取得模板StringTemplate,
的實例:
StringTemplate str = RAW
. "Today's weather is \{ getFeelsLike() }, with a temperature of \{ getTemperature() } degrees \{ getUnit() }" ;
RAW
是標準模板處理器,它產生未處理的StringTemplate
類型物件。
最後,我們將StringTemplate str
實例傳遞給處理器的 process() 方法(在我們的範例中是STR)
:
return STR.process(str);
5. 字串插值和字串模板
我們現在已經看到了使用字串模板作為字串組合技術的範例,我們可以看到它與字串插值非常相似。但是,字串模板提供了其他平台上的字串插值通常無法保證的安全性。
模板表達式是有意設計的,因此不可能將包含嵌入表達式的字串文字或文字區塊直接插入到輸出字串中。處理器的存在確保危險或不正確的字串不會透過程式碼傳播。處理器有責任驗證插值是否安全且正確。
缺少任何模板處理器將產生編譯時錯誤。此外,如果處理器無法插值,它可能會產生Exception
。
Java 根據嵌入表達式的存在來決定將“<some text>”
視為StringLiteral
或StringTemplate
。 “””<some text>”””
也是如此,以區分TextBlock
和TextBlockTemplate
。這種區別對 Java 很重要,因為儘管在這兩種情況下,字串模板都用雙引號 ( “”
) 括起來,但 String 模板的類型是java.lang.StringTemplate,
是一個接口,而不是java .lang.String java.lang.String.
六,結論
在本文中,我們討論了幾種字串組合技術並了解字串插值背後的想法。我們也了解了 Java 如何借助字串模板引入字串插值的想法。最後,我們研究了字串模板如何比一般字串插值更好、更安全地使用。
與往常一樣,程式碼可以在 GitHub 上取得。