Java国际化案例

wen java案例 2

本文目录导读:

Java国际化案例

  1. 项目结构
  2. 资源文件
  3. Java代码实现
  4. 运行结果示例
  5. 关键知识点总结

我将为您提供一个完整的Java国际化(i18n)案例,涵盖基础到进阶的使用方法。

项目结构

src/
├── main/
│   └── java/
│       └── com/example/i18n/
│           ├── Main.java
│           ├── InternationalizationDemo.java
│           └── DynamicResourceBundle.java
└── resources/
    └── messages/
        ├── messages.properties (默认英文)
        ├── messages_zh_CN.properties (简体中文)
        ├── messages_zh_TW.properties (繁体中文)
        ├── messages_fr_FR.properties (法语)
        └── messages_ja_JP.properties (日语)

资源文件

messages.properties(默认英文)

greeting=Hello, {0}!
farewell=Goodbye, {0}!
welcome=Welcome to our application
date.format=yyyy-MM-dd HH:mm:ss
current.date=Current date: {0,date,long}
balance=Your account balance is {0,number,currency}
items.in.cart=You have {0} items in your cart
online.users=Currently {0} users online
# 名词
user=User
admin=Administrator
guest=Guest
# 错误消息
error.required=Field {0} is required
error.invalid=Invalid {0} format
error.notfound={0} not found
# 菜单
menu.home=Home
menu.about=About
menu.services=Services
menu.contact=Contact

messages_zh_CN.properties(简体中文)

greeting=你好,{0}!
farewell=再见,{0}!
welcome=欢迎使用我们的应用程序
date.format=yyyy年MM月dd日 HH时mm分ss秒
current.date=当前日期:{0,date,long}
balance=您的账户余额为 {0,number,currency}
items.in.cart=您有 {0} 件商品在购物车中
online.users=当前有 {0} 个用户在线
# 名词
user=用户
admin=管理员
guest=访客
# 错误消息
error.required=字段 {0} 是必填项
error.invalid={0} 格式不正确
error.notfound=未找到{0}
# 菜单
menu.home=首页
menu.about=关于我们
menu.services=服务
menu.contact=联系方式

messages_zh_TW.properties(繁体中文)

greeting=你好,{0}!
farewell=再見,{0}!
welcome=歡迎使用我們的應用程式
date.format=yyyy年MM月dd日 HH時mm分ss秒
current.date=當前日期:{0,date,long}
balance=您的賬戶餘額為 {0,number,currency}
items.in.cart=您有 {0} 件商品在購物車中
online.users=當前有 {0} 個用戶在線
# 名詞
user=用戶
admin=管理員
guest=訪客
# 錯誤消息
error.required=字段 {0} 是必填項
error.invalid={0} 格式不正確
error.notfound=未找到{0}
# 菜單
menu.home=首頁
menu.about=關於我們
menu.services=服務
menu.contact=聯繫方式

messages_fr_FR.properties(法语)

greeting=Bonjour, {0} !
farewell=Au revoir, {0} !
welcome=Bienvenue dans notre application
date.format=dd/MM/yyyy HH:mm:ss
current.date=Date actuelle : {0,date,long}
balance=Votre solde est de {0,number,currency}
items.in.cart=Vous avez {0} articles dans votre panier
online.users=Il y a actuellement {0} utilisateurs en ligne
# 名词
user=Utilisateur
admin=Administrateur
guest=Invité
# 错误消息
error.required=Le champ {0} est requis
error.invalid=Format {0} invalide
error.notfound={0} introuvable
# 菜单
menu.home=Accueil
menu.about=À propos
menu.services=Services
menu.contact=Contact

messages_ja_JP.properties(日语)

greeting=こんにちは、{0}さん!
farewell=さようなら、{0}さん!
welcome=私たちのアプリケーションへようこそ
date.format=yyyy年MM月dd日 HH時mm分ss秒
current.date=現在の日付:{0,date,long}
balance=あなたの口座残高は {0,number,currency} です
items.in.cart=カートには {0} 個の商品があります
online.users=現在 {0} 人のユーザーがオンラインです
# 名词
user=ユーザー
admin=管理者
guest=ゲスト
# 错误消息
error.required=フィールド {0} は必須です
error.invalid={0} の形式が無効です
error.notfound={0} が見つかりません
# 菜单
menu.home=ホーム
menu.about=私たちについて
menu.services=サービス
menu.contact=お問い合わせ

Java代码实现

Main.java

package com.example.i18n;
import java.util.Locale;
import java.util.ResourceBundle;
public class Main {
    public static void main(String[] args) {
        // 基础演示
        System.out.println("=== 国际化基础演示 ===");
        InternationalizationDemo.demoBasic();
        // 高级特性演示
        System.out.println("\n=== 国际化高级特性 ===");
        InternationalizationDemo.demoAdvanced();
        // 动态资源绑定演示
        System.out.println("\n=== 动态资源绑定 ===");
        DynamicResourceBundle.demo();
        // 浏览器语言检测模拟
        System.out.println("\n=== 浏览器语言检测模拟 ===");
        simulateBrowserLanguage();
    }
    private static void simulateBrowserLanguage() {
        // 模拟不同的用户语言设置
        String[] acceptLanguages = {"zh-CN,zh;q=0.9,en;q=0.8", "en-US,en;q=0.9", "ja-JP,ja;q=0.9,en;q=0.8"};
        for (String acceptLanguage : acceptLanguages) {
            Locale locale = detectLocaleFromHeader(acceptLanguage);
            System.out.println("Accept-Language: " + acceptLanguage);
            System.out.println("Detected Locale: " + locale.getDisplayName());
            System.out.println("Language: " + locale.getLanguage());
            System.out.println("Country: " + locale.getCountry());
            System.out.println("---");
        }
    }
    private static Locale detectLocaleFromHeader(String acceptLanguage) {
        // 简单解析 Accept-Language 头
        String[] languages = acceptLanguage.split(",");
        String primary = languages[0].trim().split(";")[0];
        String[] parts = primary.split("-");
        if (parts.length == 2) {
            return new Locale(parts[0], parts[1]);
        } else {
            return new Locale(primary);
        }
    }
}

InternationalizationDemo.java

package com.example.i18n;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
public class InternationalizationDemo {
    // 基础演示
    public static void demoBasic() {
        // 支持的语言列表
        String[] supportedLocales = {"en", "zh_CN", "zh_TW", "fr_FR", "ja_JP"};
        for (String localeString : supportedLocales) {
            Locale locale = Locale.forLanguageTag(localeString.replace("_", "-"));
            ResourceBundle bundle = ResourceBundle.getBundle("messages", locale);
            System.out.println("\n=== " + locale.getDisplayName() + " ===");
            // 基础文本
            System.out.println(bundle.getString("welcome"));
            System.out.println(MessageFormat.format(bundle.getString("greeting"), "John"));
            System.out.println(MessageFormat.format(bundle.getString("farewell"), "John"));
            // 菜单
            System.out.println("Menu: " + 
                bundle.getString("menu.home") + " | " + 
                bundle.getString("menu.about") + " | " + 
                bundle.getString("menu.services") + " | " + 
                bundle.getString("menu.contact"));
        }
    }
    // 高级特性演示
    public static void demoAdvanced() {
        // 演示日期和数字格式化
        demoDateFormatting();
        demoNumberFormatting();
        // 演示复数规则
        demoPluralRules();
        // 演示选择格式
        demoChoiceFormat();
        // 演示货币格式化
        demoCurrencyFormatting();
        // 演示百分比格式化
        demoPercentFormatting();
    }
    private static void demoDateFormatting() {
        System.out.println("\n--- 日期格式化 ---");
        Locale[] locales = {
            Locale.ENGLISH, Locale.CHINA, Locale.TAIWAN, 
            Locale.FRANCE, Locale.JAPAN
        };
        Date now = new Date();
        for (Locale locale : locales) {
            DateFormat shortFormat = DateFormat.getDateTimeInstance(
                DateFormat.SHORT, DateFormat.SHORT, locale);
            DateFormat longFormat = DateFormat.getDateTimeInstance(
                DateFormat.LONG, DateFormat.LONG, locale);
            System.out.println(locale.getDisplayName() + ":");
            System.out.println("  短格式: " + shortFormat.format(now));
            System.out.println("  长格式: " + longFormat.format(now));
        }
    }
    private static void demoNumberFormatting() {
        System.out.println("\n--- 数字格式化 ---");
        double num = 1234567.89;
        Locale[] locales = {
            Locale.ENGLISH, Locale.CHINA, Locale.TAIWAN, 
            Locale.FRANCE, Locale.JAPAN
        };
        for (Locale locale : locales) {
            NumberFormat nf = NumberFormat.getNumberInstance(locale);
            System.out.println(locale.getDisplayName() + ": " + nf.format(num));
        }
    }
    private static void demoCurrencyFormatting() {
        System.out.println("\n--- 货币格式化 ---");
        double amount = 1234567.89;
        Locale[] locales = {
            Locale.US, Locale.CHINA, Locale.TAIWAN, 
            Locale.FRANCE, Locale.JAPAN
        };
        for (Locale locale : locales) {
            NumberFormat cf = NumberFormat.getCurrencyInstance(locale);
            System.out.println(locale.getDisplayName() + ": " + cf.format(amount));
        }
    }
    private static void demoPercentFormatting() {
        System.out.println("\n--- 百分比格式化 ---");
        double percent = 0.8567;
        Locale[] locales = {
            Locale.US, Locale.CHINA, Locale.FRANCE, Locale.JAPAN
        };
        for (Locale locale : locales) {
            NumberFormat pf = NumberFormat.getPercentInstance(locale);
            pf.setMaximumFractionDigits(2);
            System.out.println(locale.getDisplayName() + ": " + pf.format(percent));
        }
    }
    private static void demoPluralRules() {
        System.out.println("\n--- 复数规则演示 ---");
        String pattern = "你有一件物品|你有{0}件物品|你有{0}件物品";
        for (int i = 0; i <= 5; i++) {
            String[] parts = pattern.split("\\|");
            String result;
            if (i == 0) {
                result = "你没有任何物品";
            } else if (i == 1) {
                result = "你有一件物品";
            } else {
                result = "你有" + i + "件物品";
            }
            System.out.println(i + " -> " + result);
        }
    }
    private static void demoChoiceFormat() {
        System.out.println("\n--- 选择格式 (ChoiceFormat) ---");
        java.text.ChoiceFormat cf = new java.text.ChoiceFormat(
            "0#没有用户|1#一个用户|2#两个用户|2<多个用户"
        );
        for (int i = 0; i <= 5; i++) {
            System.out.println(i + " users: " + cf.format(i));
        }
    }
}

DynamicResourceBundle.java

package com.example.i18n;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
public class DynamicResourceBundle {
    public static void demo() {
        // 演示动态语言切换
        String[] locales = {"en", "zh_CN", "fr_FR"};
        for (String localeString : locales) {
            Locale locale = Locale.forLanguageTag(localeString.replace("_", "-"));
            System.out.println("\n--- 切换到 " + locale.getDisplayName() + " ---");
            // 创建资源绑定
            ResourceBundle bundle = getBundle(locale);
            // 演示完整的业务流程
            simulateUserInterface(bundle, locale);
        }
    }
    private static ResourceBundle getBundle(Locale locale) {
        try {
            return ResourceBundle.getBundle("messages", locale);
        } catch (MissingResourceException e) {
            System.err.println("警告: 找不到对应的资源文件,使用默认语言");
            return ResourceBundle.getBundle("messages", Locale.ENGLISH);
        }
    }
    private static void simulateUserInterface(ResourceBundle bundle, Locale locale) {
        // 模拟用户界面
        System.out.println("=== 用户界面模拟 ===");
        // 登录界面
        System.out.println("--- 登录界面 ---");
        System.out.println(bundle.getString("welcome"));
        System.out.println("用户名: John");
        // 显示信息
        System.out.println("--- 用户信息 ---");
        // 日期格式化
        java.text.DateFormat dateFormat = java.text.DateFormat.getDateInstance(
            java.text.DateFormat.MEDIUM, locale);
        Date now = new Date();
        System.out.println(bundle.getString("current.date") + " " + dateFormat.format(now));
        // 货币格式化
        java.text.NumberFormat currencyFormat = java.text.NumberFormat.getCurrencyInstance(locale);
        System.out.println(MessageFormat.format(bundle.getString("balance"), 
            currencyFormat.format(12345.67)));
        // 数字格式化
        java.text.NumberFormat numberFormat = java.text.NumberFormat.getNumberInstance(locale);
        System.out.println(MessageFormat.format(bundle.getString("items.in.cart"), 
            numberFormat.format(3)));
        // 错误消息
        System.out.println("--- 错误消息 ---");
        System.out.println(MessageFormat.format(bundle.getString("error.required"), 
            bundle.getString("user")));
        System.out.println(MessageFormat.format(bundle.getString("error.invalid"), 
            "Email"));
        // 菜单
        System.out.println("--- 菜单 ---");
        System.out.println("1. " + bundle.getString("menu.home"));
        System.out.println("2. " + bundle.getString("menu.about"));
        System.out.println("3. " + bundle.getString("menu.services"));
        System.out.println("4. " + bundle.getString("menu.contact"));
    }
}

运行结果示例

运行程序后,您将看到类似以下的输出:

=== 国际化基础演示 ===
=== English ===
Welcome to our application
Hello, John!
Goodbye, John!
Menu: Home | About | Services | Contact
=== 中文 (中国) ===
欢迎使用我们的应用程序
你好,John!
再见,John!
Menu: 首页 | 关于我们 | 服务 | 联系方式
=== 中文 (台湾) ===
歡迎使用我們的應用程式
你好,John!
再見,John!
Menu: 首頁 | 關於我們 | 服務 | 聯繫方式
=== 法语 (法国) ===
Bienvenue dans notre application
Bonjour, John !
Au revoir, John !
Menu: Accueil | À propos | Services | Contact
=== 日语 (日本) ===
私たちのアプリケーションへようこそ
こんにちは、Johnさん!
さようなら、Johnさん!
Menu: ホーム | 私たちについて | サービス | お問い合わせ
=== 国际化高级特性 ===
--- 日期格式化 ---
English: 1/16/24, 10:30 AM
中文 (中国): 2024年1月16日 上午10时30分
中文 (台湾): 2024年1月16日 上午10時30分
法语 (法国): 16/01/2024 10:30
日语 (日本): 2024/01/16 10:30
--- 数字格式化 ---
English: 1,234,567.89
中文 (中国): 1,234,567.89
中文 (台湾): 1,234,567.89
法语 (法国): 1 234 567,89
日语 (日本): 1,234,567.89
--- 货币格式化 ---
美国: $1,234,567.89
中国: ¥1,234,567.89
台湾: NT$1,234,567.89
法国: 1 234 567,89 €
日本: ¥1,234,567.89
...

关键知识点总结

1 资源文件命名规则

  • 基础名称: messages.properties
  • 特定语言: messages_zh_CN.properties
  • 特定地区: messages_zh_TW.properties

2 主要类

  • Locale: 表示特定的地理、政治或文化区域
  • ResourceBundle: 加载和管理资源文件
  • MessageFormat: 格式化包含占位符的消息
  • NumberFormat: 格式化数字、货币、百分比
  • DateFormat: 格式化日期和时间

3 最佳实践

// 1. 使用常量定义Locale
public class LocaleConstants {
    public static final Locale ENGLISH = Locale.US;
    public static final Locale CHINESE = Locale.CHINA;
    public static final Locale JAPANESE = Locale.JAPAN;
}
// 2. 封装资源访问
public class I18nManager {
    private static ResourceBundle bundle;
    public static String getString(String key) {
        return bundle.getString(key);
    }
    public static String getFormattedString(String key, Object... args) {
        return MessageFormat.format(bundle.getString(key), args);
    }
}
// 3. 使用属性模式(推荐)
public class Messages {
    private static final String BASE_NAME = "messages";
    public static String get(String key, Locale locale) {
        return ResourceBundle.getBundle(BASE_NAME, locale).getString(key);
    }
    public static String get(String key, Locale locale, Object... args) {
        return MessageFormat.format(get(key, locale), args);
    }
}

这个案例展示了Java国际化的完整实现,包括基础文本翻译、日期/数字/货币格式化、复数规则处理等核心功能,您可以根据实际项目需求进行调整和扩展。

抱歉,评论功能暂时关闭!