String.format() 是 Java 5 引入的靜態工廠方法,提供類 C 語言 sprintf 風格的格式化能力,支援本地化、多參數、複雜類型轉換。兩種重載形式:
format(String format, Object... args) — 使用默認 Localeformat(Locale locale, String format, Object... args) — 指定 Locale,適用於國際化場景底層委託 java.util.Formatter 實現,線程安全,性能優於手動拼接。
| 轉換符 | 說明 | 示例輸出 | 適用類型 |
|---|---|---|---|
%s | 字符串 | "mingrisoft" | 任意對象(調用 toString) |
%c | 單字符 | 'm' | char, Character, byte, short, int |
%b | 布爾值 | "true" | boolean, Boolean(非 null 為 true) |
%d | 十進制整數 | 99 | byte, short, int, long, BigInteger |
%x / %X | 十六進制整數 | "ff" / "FF" | 同上 |
%o | 八進制整數 | "77" | 同上 |
%f | 浮點數(定點) | "99.990000" | float, double, BigDecimal |
%e / %E | 科學計數法 | "9.999000e+01" | 同上 |
%g / %G | 通用浮點(短者優先) | "99.99" | 同上 |
%a / %A | 十六進制浮點 | "0x1.91eb851eb851fp6" | float, double |
%h | 哈希碼(十六進制) | "4d6f636b" | 任意對象 |
%% | 字面百分號 | "%" | — |
%n | 平台換行符 | Windows:\r\n / Linux:\n | — |
語法:%tX 或 %TX,X 為具體子格式:
| 子格式 | 含義 | 示例 |
|---|---|---|
%tF | ISO 8601 日期 (yyyy-MM-dd) | 2024-05-20 |
%tT | 24小時制時間 (HH:mm:ss) | 14:30:05 |
%tr | 12小時制時間 (hh:mm:ss a) | 02:30:05 PM |
%tY / %ty | 年 (四位/兩位) | 2024 / 24 |
%tm / %td | 月/日 (兩位) | 05 / 20 |
%tH / %tI | 時 (24/12制) | 14 / 02 |
%tM / %tS | 分/秒 | 30 / 05 |
%tL / %tN | 毫秒/納秒 (三位/九位) | 123 / 123456789 |
%tz | 時區偏移 (+0800) | +0800 |
%tp | 上午/下午標記 (a.m./p.m.) | 下午 |
技巧:同一參數可被多次引用,使用 %<tF 復用前一個日期參數,避免重複傳遞。
// 格式語法:%[參數索引$][標誌][寬度][.精度]轉換符
String.format("%1$05d", 42); // "00042" 索引1、前導補0、寬度5
String.format("%,d", 1234567); // "1,234,567" 分組分隔符
String.format("%+d", 42); // "+42" 強制顯示正負號
String.format("% d", 42); // " 42" 正數前留空格
String.format("%.2f", 3.14159); // "3.14" 保留2位小數
String.format("%-10s", "Hi"); // "Hi " 左對齊
String.format("%(d", -42); // "(42)" 負數用括號包裹
String.format("%#x", 255); // "0xff" 顯示前綴
String.format("%,.2f", 1234.5); // "1,234.50" 組合使用
public class FormatDemo {
public static void main(String[] args) {
// 基礎字符串插值
System.out.println(String.format("Hi, %s", "王力")); // Hi, 王力
System.out.println(String.format("Hi, %s:%s.%s", "王南","王力","王張")); // Hi, 王南:王力.王張
// printf 直接輸出到控制台
System.out.printf("字母a的大寫是:%c %n", 'A');
System.out.printf("3>7的結果是:%b %n", 3>7);
System.out.printf("100的一半是:%d %n", 100/2);
System.out.printf("100的16進制數是:%x %n", 100);
System.out.printf("100的8進制數是:%o %n", 100);
// 浮點數多種表現
double price = 50 * 0.85; // 42.5
System.out.printf("50元的書打8.5折扣是:%f 元%n", price); // 42.500000
System.out.printf("上面價格的16進制數是:%a %n", price); // 0x1.54ccccccccccdp5
System.out.printf("上面價格的指數表示:%e %n", price); // 4.250000e+01
System.out.printf("上面價格的指數和浮點數結果的長度較短的是:%g %n", price); // 42.5
// 百分號、哈希碼、換行
System.out.printf("上面的折扣是%d%% %n", 85); // 85%
System.out.printf("字母A的散列碼是:%h %n", 'A'); // 41
// 日期時間格式化
java.util.Date now = new java.util.Date();
System.out.printf("今天是:%tF %n", now); // 2024-05-20
System.out.printf("現在時間:%tT %n", now); // 14:30:05
System.out.printf("完整時間戳:%tc %n", now); // Mon May 20 14:30:05 CST 2024
}
}
%1$s 顯式指定索引,避免參數順序不匹配導致 MissingFormatArgumentException。%s 遇到 null 輸出 "null",若需空字符串請預先 Objects.toString(obj, "")。Formatter 或改用 StringBuilder + append,避免反复解析格式字符串。Locale.US 或用戶 Locale。String.formatted() 實例方法鏈式調用;複雜模板場景考慮 FreeMarker、Thymeleaf 等模板引擎。String.format 是 Java 格式化輸出的瑞士軍刀,掌握轉換符、標誌符、精度控制、日期時間子格式,即可優雅處理 90% 以上的字符串構建需求。記住:格式字符串即文檔,善用索引與標誌符,讓代碼自説明、易維護。