java.text.MessageFormat 提供基於位置參數的字串模板替換功能,適用於國際化訊息、日誌格式化、動態 SQL 構建等場景。本文詳解核心用法、參數匹配規則與實戰注意事項。
String template = "用戶 {0} 於 {1} 登入系統,IP: {2}";
Object[] params = {"張三", new Date(), "192.168.1.100"};
String result = MessageFormat.format(template, params);
// 結果:用戶 張三 於 2024-01-15 10:30:45 登入系統,IP: 192.168.1.100
| 規則 | 說明 | 錯誤示範 |
|---|---|---|
| 參數索引從 0 開始 | {0}、{1}... 對應陣列下標 | {1} 對應第一個參數 → 索引錯位 |
| 參數個數須匹配 | 模板中最大索引 N 需 params.length > N | 模板 {2} 但陣列僅 2 個元素 → ArrayIndexOutOfBoundsException |
| 重複索引可複用 | {0} 您好,{0} 歡迎回來 | 無 |
| 支援格式化子模式 | {0,date,yyyy-MM-dd}、{1,number,#.##} | 格式語法錯誤 → IllegalArgumentException |
| 單引號轉義 | '{' → ''{','}' → ''}' | 直接寫 { 會被視為參數開始 |
String pattern = "總額: {0,number,¥#,##0.00} | 日期: {1,date,yyyy年MM月dd日} | 比例: {2,number,##0%}";
Object[] args = {12345.678, new Date(), 0.856};
MessageFormat.format(pattern, args);
// 總額: ¥12,345.68 | 日期: 2024年01月15日 | 比例: 86%
ResourceBundle,不同語系維護獨立模板檔[ERROR] {0} - {1,date,HH:mm:ss} - {2}WHERE user_id = {0} AND status = {1}(注意:非替代 PreparedStatement,防注入)| 方案 | 效能 | 功能豐富度 | 適用場景 |
|---|---|---|---|
MessageFormat | 中等(解析開銷) | 高(格式化、複數、國際化) | 複雜模板、國際化、需格式化 |
String.format | 中等 | 中(C 風格格式化) | 簡單格式化、類 printf 需求 |
StringBuilder + append | 最高 | 低(無模板語法) | 高頻、簡單拼接、效能敏感 |
| 模板引擎 | 低(初始化) | 極高(邏輯、迴圈、繼承) | 複雜報表、頁面渲染、郵件模板 |
MessageFormat.format("'{0}'", "test") 輸出 'test' 而非 test。需寫 "''{0}''" 輸出 'test'null 會輸出 "null" 字串,建議預先轉換 Objects.toString(param, "")MessageFormat 非執行緒安全,勿作為靜態共享實例,每次使用新建或使用 format(pattern, args) 靜態方法new MessageFormat(pattern, locale)MessageFormat 是 Java 標準庫中功能最完整的模板引擎,特別適合需要格式化、國際化、業務模板外部化的場景。掌握其索引規則、格式化語法與轉義機制,能顯著提升字串構建的靈活性與維護性。