应避免向locale构造函数传null或空字符串,推荐用locale.forlanguagetag("zh-cn");资源文件名须严格匹配locale,如messages_zh_cn.properties;web应用中勿用locale.getdefault(),应从http请求头获取语言信息。

Locale 构造时别传空字符串或 null
传 null 或空字符串给 Locale 构造函数,不会报错,但后续调用 getDisplayName()、getLanguage() 等方法时可能返回空、乱码,甚至触发 NullPointerException(尤其在某些 JDK 版本中对 toString() 的内部调用)。
常见错误现象:界面语言突然变英文、资源束加载失败、日志里出现 en__ 这类非法标签。
- 用
new Locale("zh", "CN"),别用new Locale("", "CN")或new Locale(null, "CN") - 从用户输入或配置读取语言代码时,先做非空和格式校验:
lang != null && !lang.trim().isEmpty() - JDK 9+ 推荐用
Locale.forLanguageTag("zh-CN"),它会自动标准化并拒绝非法 tag(如zh--CN)
ResourceBundle 加载失败不等于 Locale 不存在
ResourceBundle.getBundle("messages", locale) 返回 null 或抛 MissingResourceException,往往不是 locale 本身有问题,而是对应资源文件没按命名规范放好。
使用场景:切换语言后文字没变、控制台反复打印“Can't find bundle for base name messages”。
立即学习“Java免费学习笔记(深入)”;
IEStore是一款B2C独立网上商店系统,适合企业及个人快速构建个性化网上商店。系统是基于PHP语言及MYSQL数据库构架开发的跨平台开源程序。IEStore网上商店系统不仅在产品功能、稳定性、安全性和SEO支持(搜索引擎优化)等方面具有在同类产品领先地位,重要的是在功能架构上、操作上符合国际化标准,成为国际化电子商务的最佳软件选择之一。功能概要国际化标准IEStore网上商店系统是一个带有多国
- 资源文件名必须严格匹配:
messages_zh_CN.properties→ 对应new Locale("zh", "CN");messages_en_US.properties→ 对应new Locale("en", "US") - 默认 fallback 是
messages.properties(无下划线),不是messages_en.properties;如果只写了后者,且 locale 是en_GB,它会跳过messages_en直接找messages - 确保资源文件在 classpath 下,IDE 中有时需手动刷新或标记为 Resources Root
Locale.getDefault() 在服务器上不可靠
Web 应用或微服务里直接调用 Locale.getDefault(),大概率拿到的是 JVM 启动时的系统 locale(比如服务器是 en_US),跟用户浏览器语言完全无关。
性能影响:这个调用本身很快,但用错会导致整个 I18N 链路失效,所有用户看到同一套语言。
- HTTP 请求中语言信息来自
Accept-Languageheader,Spring MVC 用AcceptHeaderLocaleResolver,Servlet 原生可用request.getLocale() - 不要在 static 块或单例初始化时缓存
Locale.getDefault(),它不会随请求变化 - 多线程环境下,
Locale.setDefault()是全局生效的,会污染其他请求 —— 绝对禁止在 request scope 里调用它
中文地区用 zh-CN 还是 zh-SG?
简体中文用户不一定都该用 zh_CN。新加坡、马来西亚用户习惯用 zh_SG(繁体转简体规则不同)、zh_MY,连日期格式、货币符号、甚至“软件”叫“软体”都有差异。
兼容性影响:JDK 自带的 DateFormat 和 NumberFormat 对不同 Locale 的行为差异很大,比如 zh_CN 的千分位是逗号,zh_TW 是空白。
- 浏览器发送的
Accept-Language: zh-CN,zh;q=0.9表示首选zh_CN,次选通用zh;服务端应优先匹配精确 locale,再 fallback 到语言族 - 若业务覆盖东南亚,建议资源文件至少包含
messages_zh_CN.properties、messages_zh_SG.properties、messages_zh_TW.properties - 避免硬编码
new Locale("zh", "CN")做逻辑分支,用locale.getCountry()动态判断更稳妥
真正麻烦的不是选哪个 locale,而是同一份中文文案在不同地区要人工校对三遍——标点、度量衡、法律术语、甚至“登录”和“登入”的用词偏好。









