Java Gold対策:ローカライズ


はじめに

本稿は、Java Goldの学習のまとめとして以下項目についてまとめる。
(同じくJava Goldを学習中やローカライズについて知りたい方の参考になればと。)

  • ロケール
  • リソースバンドル

ロケールとは

java.util.Locale

言語や国ごとに異なるものの表記規則を示す。
# 例:単位・記号・日付・通貨など

アプリケーションを使用した国毎に、表示を変えたい場合などにロケールを利用する。
(アプリを使用する国によって文字を日本語・英語と分けたり等)

インスタンス生成方法は主に以下3種類ある。

  • new
  • Localクラスの定数
  • getDefault()メソッド

■ 主なコンストラクタ・メソッド

コンストラクタ 内容
Local(String language, String country) 引数の言語/国コードからオブジェクトを生成
// newによるインスタンス生成
// ja・en:言語名コード | JP・US:国名コード
Locale localeJp = new Locale("ja","JP");  // 日本のロケール
Locale localeUs = new Locale("en","US");  // アメリカのロケール

// Localeクラスの定数によるインスタンス生成
Locale localeJp = Locale.JAPAN;
Locale localeUs = Locale.US;

// getDefault()メソッドによるインスタンス生成
// 日本で実行すると日本のLocaleインスタンスが生成される
Locale localeJp = Locale.getDefault();
メソッド 内容
static getDefault() デフォルトロケールの現在の値を取得
final String getDisplayCountry() ロケールの国名を返却
final String getDisplayLanguage() ロケールの言語名を返却
String getCountry() ロケールの国名コードを返却
String getLanguage() ロケールの言語名コードを返却
// ja_JP が格納される(OSが日本の場合)
Locale locale = Locale.getDefault();

// 日本 が格納される
String country = locale.getDisplayCountry();

// 日本語 が格納される
String language = locale.getDisplayLanguage();

// JP が格納される
String country_code = locale.getCountry();

// ja が格納される
String language_code = locale.getLanguage();

// 備考:他のインスタンス生成方法
Locale locale = new Locale.Builder().setLanguage("ja")
                                    .setScript("Jpan")
                                    .setRegion("JP")
                                    .build();
// setScript():引数はISO 15924 alpha-4スクリプトコード(Javadoc参照)
// build():Locale.Builderのメソッドで、Localオブジェクトを生成

リソースバンドル

java.util.ResourceBundle

言語や国ごとに異なる表記規則をロケールに応じて対応させる。
これによりロケールに応じて日本表記や英語表記を切り替えることが出来る。

主に使用するメソッドは以下の通り。

メソッド 内容
boolean containsKey(String key) 引数で指定されたキーがリソースにある場合はtrueを返却
final Object getObject 引数で指定されたキーに紐づくオブジェトを返却
final String getString(String key) 引数で指定されたキーに紐づく文字列を返却
final String[] getStringArray(String key) 引数で指定されたキーに紐づく文字列の配列を返却
Set keySet() バンドルに含まれるすべてのキーを返却

また、サブクラスとして以下がある。

サブクラス 内容
ListResourceBundle ロケール用のリソースを便利かつ使いやすいリストで管理
PropertyResourceBuilder プロパティファイルからの一連のstatic文字列を使用してロケール用のリソースを管理

■ ListResourceBundleを使用する場合

こちらを使用する場合の定義ルールは以下の通り。

  • 定義方法
    • ListResourceBundleを継承したpublicクラスを作成する
    • getContents()メソッドをオーバーライドして配列でリソースのリストを作成する
    • リソースは、キーと値を要素とする配列として作成

引用

▼ 実装例

Resource.java
public class Resource extends ListResourceBundle {

    public Object[][] getContents() {
        Object[][] contents = {
                {"apple", "リンゴ"},
                {"orange", "オレンジ"}
        };
        return contents;
    }
}
Resource_en_US.java
public class Resource_en extends ListResourceBundle {

    protected Object[][] getContents() {
        Object[][] contents = {
                {"apple", "apple"},
                {"orange", "orange"}
        };
        return contents;
    }
}

基底名言語コード国コード.javaとすることでロケール
のオブジェクトに対応した言語のファイルが参照される。

デフォルトのロケールインスタンスの場合は基底名のリソースが参照される。
また、ロケールのインスタンスに言語コードのみ指定した場合は、基底名の後に言語コードのみで良い。

Main.java

// 出力結果は以下の通り
// リンゴ:オレンジ
// apple:orange

class Main {
    public static void main(String[] args) {

        Locale localeJa = Locale.JAPAN;
        Locale localeUs = Locale.US;

        // 第二引数の指定がない場合デフォルトロケートを指定する
        List<Locale> locales =
                new ArrayList<Locale>(Arrays.asList(localeJa, localeUs));

        for(Locale locale : locales) {
            // パッケージ名.ファイル名を指定
            ResourceBundle rb =
                ResourceBundle.getBundle("resource.Resource", locale);

            // String以外を取得する場合はgetObjectメソッドを使用してキャストする
            System.out.println(rb.getString("apple") + ":" + rb.getString("orange"));
        }
    }
}

■ PropertyResourceBuilderを使用する場合

こちらを使用する場合の定義ルールは以下の通り。

  • プロパティファイル名は、基底名言語コード国コード.properties
  • リソースのキーと値はプロパティファイル内にキー = 値の形の形で記載

▼ 実装例

Source.properties
apple=J_apple
orange=J_orange
Source_en_US.properties
apple=U_apple
orange=U_orange
Main.java

// 出力結果
// J_appleJ_orange
// U_appleU_orange

class Main {
    public static void main(String[] args) throws MalformedURLException {

        File dicDir = Paths.get(".\\resource").toFile();

        URLClassLoader urlLoader;
        urlLoader = new URLClassLoader(new URL[]{dicDir.toURI().toURL()});

        Locale localeJp = Locale.JAPAN;
        Locale localeUs = Locale.US;

        List<Locale> locales =
                new ArrayList<Locale>(Arrays.asList(localeJp, localeUs));

        for (Locale locale : locales) {
            // ファイル名のみ指定
            ResourceBundle rb =
                    ResourceBundle.getBundle("Source" ,locale ,urlLoader);

            System.out.println(rb.getString("apple") + rb.getString("orange"));

        }
    }
}

参考文献