玩转 Java 国际化:进击的Locale!

文章目录

一、什么是 `Locale`?
二、如何创建 `Locale`?

✅ 1. 使用标准常量(推荐)
✅ 2. 使用构造函数
✅ 3. 使用语言标签(推荐方式)
✅ 4. 使用 `Locale.Builder`

三、常用方法与应用场景

1. 🌐 国际化消息处理

📌 使用方式一:ResourceBundle
📌 使用方式二:Spring 的 `MessageSource`

2. 💱 格式化(时间、数字、货币)

🕓 示例:格式化日期
💵 示例:货币格式
🔢 示例:数字格式

3. 🧑‍💻 用户界面多语言支持

✅ 场景示例
📦 技术实现方式

4. 🧭 区域性设置与偏好

🧪 示例:使用 Collator 排序
🌍 获取默认 Locale
🔁 修改默认 Locale(不推荐直接修改)

5. ✅ 总结

四、JDK 10 中的增强 ✨

🔹 1. `Locale.filterTags()` 新增
🔹 2. Unicode 扩展支持增强
🔹 3. `Locale.Builder` 扩展能力加强

五、最佳实践建议 ✅
六、小结 🧩

在构建多语言应用时,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 使用 LocaleMessageSource 配合,实现 Web 应用的国际化:

@Autowired
private MessageSource messageSource;

public String welcome(Locale locale) {
            
    return messageSource.getMessage("welcome", null, locale);
}

自动根据用户的 Accept-Language 头来选择合适的语言
配合前端国际化 cookie、参数、拦截器效果更好


2. 💱 格式化(时间、数字、货币)

Java 的格式化工具类,如 DateTimeFormatterNumberFormat 等都接受 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 新特性专栏!一起来变得更强大吧 🚀

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容