messageformat 是 java 中用于结构化消息格式化的工具,支持多语言、日期数字本地化及占位符嵌套,需注意编码、类型匹配与 locale 设置。

MessageFormat 是 Java 中处理带参数消息的核心工具,特别适合需要多语言支持的场景。它不靠字符串拼接,而是用结构化占位符统一管理动态内容,让中文、英文、日文等不同语言的消息模板既能复用逻辑,又能各自适配本地习惯。
占位符写法与基本替换
最常用的是索引式占位符,比如 {0}、{1},对应传入参数数组的第 0、第 1 个元素:
- {0}:纯位置引用,适用于简单文本替换,如“欢迎,{0}!” → format(new Object[]{"张三"}) → “欢迎,张三!”
- {0,date}:自动按默认日期格式处理,传入 Date 对象即可
- {1,number,currency}:把数字转为本地货币样式,如传入 1234.5 → 显示为 ¥1,234.50(中文环境)或 $1,234.50(英文环境)
- {2,number,#,##0.00}:指定自定义数字模式,保留两位小数并加千分位
与资源文件配合做真正国际化
把不同语言的模板抽到 properties 文件里,运行时按 Locale 自动加载:
- messages_zh_CN.properties:order.status=您的订单 {0} 已于 {1,date,short} {1,time,short} 发货
- messages_en_US.properties:order.status=Your order {0} shipped on {1,date,short} at {1,time,short}
- 代码中用 ResourceBundle.getBundle("messages", locale) 获取对应语言包,再用 MessageFormat.format() 填充参数
- 注意:MessageFormat 构造时可显式传入 Locale,确保日期/数字格式与语言包一致
处理复杂语义:复数与选择(需搭配 ICU 或 Spring)
标准 Java MessageFormat 不直接支持“1 条消息 / 2 条消息”这种复数变化,但可通过扩展实现:
- Spring 的 MessageSource + MessageFormat 底层支持 {0,choice,0#无|1#一个|1
- 更推荐前端或现代后端用 ICU 格式(如 Intl.MessageFormat),支持 {num, plural, =0{无} =1{一个} other{#个}},翻译人员也更易理解
- 若必须用原生 Java,可用嵌套 MessageFormat:先格式化复数部分为字符串,再作为参数填入外层模板
避坑提醒:常见错误点
实际开发中容易忽略这些细节:
- 占位符索引超出参数数组长度 → 抛 IllegalArgumentException,建议预校验或用 try-catch 包裹 format 调用
- 日期/数字参数类型不匹配(比如传 String 给 {0,date})→ 格式化失败,返回原始占位符文本
- properties 文件未用 UTF-8 编码保存中文 → 出现乱码,需在 IDE 和构建脚本中统一设为 UTF-8
- 没有为 MessageFormat 指定 Locale,导致数字千分位、货币符号不符合目标地区习惯










