文章摘要(AI生成)
Locale 是 Java 国际化(i18n)功能的核心类之一,用于表示特定的地理、政治或文化区域,如“中文-中国”。创建 Locale 对象的方法多样,包括使用标准常量、构造函数、语言标签及 Locale.Builder。Locale 主要应用于国际化消息处理、格式化(时间、数字和货币)、用户界面多语言支持和区域性设置等场景。通过 ResourceBundle 和 Spring 的 MessageSource,Java 能够根据 Locale 加载适合的资源文件,实现多语言支持。在格式化方面,Java 提供了如 DateTimeFormatter 和 NumberFormat 等工具类,这些类均接受 Locale 参数以符合本地习惯。此外,JDK 10 引入了 Locale.filterTags() 等增强功能。最佳实践建议中强调使用 Locale 进行动态内容展示,从而提升用户体验。
在构建多语言应用时,Java 提供了完善的国际化(i18n)支持,而其中的核心类之一便是 java.util.Locale
。它代表了一个特定的地理、政治或文化区域,如“中文-中国”、“英语-美国”等。本文将带你全面了解 Locale
的基础知识、常见用法,以及 JDK 10 中的一些重要增强。
一、什么是 Locale
?
Locale
是 Java 国际化功能的基石。它不是日期格式或翻译资源本身,而是用来标识“语言环境”的对象。系统根据 Locale
来选择合适的资源、格式和行为。
例如,以下代码可根据不同地区格式化数字和日期:
NumberFormat format = NumberFormat.getInstance(Locale.FRANCE);
System.out.println(format.format(123456.78)); // 输出 123 456,78
二、如何创建 Locale
?
Java 提供了多种方式来创建 Locale
对象:
✅ 1. 使用标准常量(推荐)
Locale locale = Locale.US; // 等同于 new Locale("en", "US")
✅ 2. 使用构造函数
Locale locale = new Locale("zh", "CN"); // 中文-中国
✅ 3. 使用语言标签(推荐方式)
Locale locale = Locale.forLanguageTag("en-GB"); // 英语-英国
这种方式符合 BCP 47 语言标签标准,更通用、更易与 Web 接口集成。
✅ 4. 使用 Locale.Builder
适合动态构建复杂的 Locale
:
Locale locale = new Locale.Builder()
.setLanguage("ja")
.setRegion("JP")
.setScript("Latn")
.build();
三、常用方法与应用场景
1. 🌐 国际化消息处理
Java 使用 Locale
来加载针对不同语言/地区的资源文件,实现文本多语言支持。
📌 使用方式一:ResourceBundle
Locale locale = new Locale("fr", "FR"); // 法国法语
ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);
System.out.println(bundle.getString("welcome")); // Bonjour
- 文件命名如
messages_fr_FR.properties
- 编码逻辑通过
Locale
自动加载匹配语言的资源
📌 使用方式二:Spring 的 MessageSource
Spring 使用 Locale
与 MessageSource
配合,实现 Web 应用的国际化:
@Autowired
private MessageSource messageSource;
public String welcome(Locale locale) {
return messageSource.getMessage("welcome", null, locale);
}
- 自动根据用户的
Accept-Language
头来选择合适的语言 - 配合前端国际化 cookie、参数、拦截器效果更好
2. 💱 格式化(时间、数字、货币)
Java 的格式化工具类,如 DateTimeFormatter
、NumberFormat
等都接受 Locale
参数,生成符合本地习惯的格式。
🕓 示例:格式化日期
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE, d MMMM yyyy", Locale.FRANCE);
System.out.println(LocalDate.now().format(formatter)); // jeudi, 10 mai 2025
💵 示例:货币格式
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.JAPAN);
System.out.println(nf.format(10000)); // ¥10,000
🔢 示例:数字格式
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMANY);
System.out.println(nf.format(1234567.89)); // 1.234.567,89
3. 🧑💻 用户界面多语言支持
当应用需要根据用户语言动态展示内容时,Locale
起到了核心作用。
✅ 场景示例
- 多语言按钮名称、提示文本
- 语言切换后界面自动刷新内容
- 与前端(Vue/React/i18next)联动
📦 技术实现方式
-
Java 后端根据请求参数或 cookie 设置
Locale
-
Spring MVC 使用
LocaleResolver
自动应用该语言环境,其提供了多种实现:AcceptHeaderLocaleResolver
(默认,从浏览器请求头解析)SessionLocaleResolver
CookieLocaleResolver
示例配置(使用 Session):
@Bean public LocaleResolver localeResolver() { SessionLocaleResolver resolver = new SessionLocaleResolver(); resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE); return resolver; }
-
页面模板通过
#messages.welcome
等动态展示文本
4. 🧭 区域性设置与偏好
Locale
不只是语言,它还代表区域性规则,如:
- 排序规则(德语“ä”在 A 之后)
- 比较方式(忽略重音、区分大小写)
- 默认区域偏好设置(语言、国家、货币)
🧪 示例:使用 Collator 排序
List<String> names = Arrays.asList("äpfel", "Apfel", "Banane");
Collator collator = Collator.getInstance(Locale.GERMAN);
Collections.sort(names, collator);
System.out.println(names); // [Apfel, äpfel, Banane]
🌍 获取默认 Locale
Locale defaultLocale = Locale.getDefault();
System.out.println(defaultLocale); // zh_CN(取决于操作系统设置)
🔁 修改默认 Locale(不推荐直接修改)
Locale.setDefault(Locale.US);
5. ✅ 总结
使用场景 | 示例技术/类 | 说明 |
---|---|---|
国际化文本 | ResourceBundle , MessageSource |
通过不同 Locale 加载不同语言资源 |
格式化 | DateTimeFormatter , NumberFormat |
显示本地化的日期、时间、数字、货币 |
多语言 UI | Spring MVC, Thymeleaf | 根据 Locale 显示不同文本内容 |
排序与比较 | Collator , RuleBasedCollator |
根据语言规则进行字符串排序与匹配 |
默认偏好设置 | Locale.getDefault() |
决定默认显示语言和格式 |
四、JDK 10 中的增强 ✨
JDK 10 对 Locale
做了一些重要的功能增强,提升了其在全球化应用中的实用性:
🔹 1. Locale.filterTags()
新增
用于过滤一组语言标签,找出最匹配用户首选语言的 Locale:
List<String> tags = List.of("zh-CN", "en-US", "fr-FR");
List<Locale.LanguageRange> ranges = Locale.LanguageRange.parse("en-US;q=0.8,zh-CN;q=1.0");
List<String> matches = Locale.filterTags(ranges, tags);
// 返回 ["zh-CN", "en-US"]
这对于浏览器语言协商、多语言 UI 自动选择极其有用。
🔹 2. Unicode 扩展支持增强
你现在可以更清晰地指定数字系统、日历系统等扩展参数:
Locale locale = Locale.forLanguageTag("en-US-u-ca-islamic-nu-thai");
这表示“美国英语,使用伊斯兰日历,使用泰语数字系统”。
🔹 3. Locale.Builder
扩展能力加强
Locale.Builder
可以更灵活地设置脚本、Unicode 属性,对多地区支持更友好。
五、最佳实践建议 ✅
建议 | 原因 |
---|---|
使用 Locale.forLanguageTag() |
与 Web、配置文件兼容性更好 |
避免使用系统默认 Locale |
系统默认可能与用户语言不一致 |
不要硬编码语言,使用 ResourceBundle |
有利于后期扩展多语言 |
在格式化数字/日期/货币时始终传入 Locale | 防止输出不一致 |
使用 Locale.filter() 做首选匹配 |
支持多语言用户选择首选语言环境(类似浏览器语言协商) |
六、小结 🧩
Locale
是 Java 国际化的核心组件,决定了 UI 展示、数据格式化、排序等行为。- JDK 10 引入了新的语言标签过滤 API、增强了 Unicode 支持,进一步提升了 Locale 的灵活性和表达力。
- 在现代多语言、多地区的应用中,合理使用
Locale
是提升用户体验的关键。
📢 你在项目中使用过 Locale
吗?是否已经尝试了 JDK 10 的新功能?欢迎留言分享你的经验与看法!
想了解更多 JDK 新特性,提升开发效率?欢迎关注我的专栏 👉 JDK 新特性专栏!一起来变得更强大吧 🚀
评论区