LoginSignup
2
3

More than 3 years have passed since last update.

Java Gold対策:ローカライズ

Last updated at Posted at 2020-07-05

はじめに

本稿は、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
  • リソースのキーと値はプロパティファイル内にキー = 値の形の形で記載

▼ 実装例

image.png

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"));

        }
    }
}

参考文献

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3