モジュール java.base
パッケージ java.util

クラスResourceBundle

java.lang.Object
java.util.ResourceBundle
直系の既知のサブクラス:
ListResourceBundle, PropertyResourceBundle

public abstract class ResourceBundle extends Object
リソース・バンドルには、ロケール固有のオブジェクトが含まれます。 プログラムでStringなどのロケール固有のリソースが必要なときは、現在のユーザーのロケールに合ったリソース・バンドルからロードできます。 このように、リソース・バンドルから、ロケール固有の情報のすべてでなくてもその大部分を切り離すことで、ユーザーのロケールにはほとんど依存しないプログラム・コードを書くことができます。

これにより、以下の特徴を持つプログラムを書くことが可能になります。

  • 異なる言語への地域対応、または翻訳が容易
  • 複数のロケールを同時に処理可能
  • 将来サポートするロケールを追加する際の修正が容易

リソース・バンドルはファミリに属しています。そのファミリでは、メンバーは共通の基底名を共有していますが、ファミリ名にはロケールを識別する追加コンポーネントも含まれています。 たとえば、リソース・バンドルのファミリの基底名は「MyResources」です。 ファミリは、ファミリと同じ名前(MyResources)で、特定のロケールがサポートされない場合は、最後の手段のバンドルとして使用される、デフォルトのリソース・バントルを持つ必要があります。 また、ファミリは、必要なだけの数のロケール固有のメンバーを提供することができます。たとえば、「MyResources_de」と名付けられたドイツのメンバーなどです。

ファミリの各リソース・バンドルには同じ項目がありますが、こうした項目は当該リソース・バンドルにより表されるロケールに合わせて翻訳されています。 たとえば、「MyResources」と「MyResources_de」の両方に、操作を取り消すためのボタンで使用されるStringがあるとします。 そのStringに、「MyResources」では「Cancel」を格納し、「MyResources_de」では「Abbrechen」を格納することができます。

同じ言語を使用するロケールでも国によってリソースが異なるときは、特殊化が可能です。たとえば、「MyResources_de_CH」には、スイス(CH)系のドイツ語(de)のオブジェクトが含まれています。 リソースの一部だけを修正することもできます。

プログラムでロケール固有のオブジェクトが必要なときは、getBundleメソッドを使用してResourceBundleクラスをロードします。

ResourceBundle myResources =
     ResourceBundle.getBundle("MyResources", currentLocale);

リソース・バンドルは、キーと値のペアになっています。 キーは、バンドルのロケール固有のオブジェクトを一意に識別します。 キーと値の2つのペアが含まれているListResourceBundleの例を示します。

public class MyResources extends ListResourceBundle {
    protected Object[][] getContents() {
        return new Object[][] {
            // LOCALIZE THE SECOND STRING OF EACH ARRAY (e.g., "OK")
            {"OkKey", "OK"},
            {"CancelKey", "Cancel"},
            // END OF MATERIAL TO LOCALIZE
       };
    }
}
キーは常にStringです。 この例では、キーは「OkKey」と「CancelKey」です。 前述した例では、値「OK」と「Cancel」もStringですが、必ずしもそうである必要はありません。 値は、どの型のオブジェクトでも可能です。

リソース・バンドルから適切なgetterメソッドを使用してオブジェクトを検索します。 「OkKey」と「CancelKey」はどちらも文字列なので、取得にはgetStringを使用します。

button1 = new Button(myResources.getString("OkKey"));
button2 = new Button(myResources.getString("CancelKey"));
getterメソッドは、すべて引数としてキーを要求し、検出したオブジェクトを返します。 オブジェクトが見つからない場合、getterメソッドはMissingResourceExceptionをスローします。

getString以外に、ResourceBundleでは、文字列配列を取得するgetStringArrayメソッドも提供します。同様に、ほかの型のオブジェクトを取得するジェネリックgetObjectメソッドも提供します。 getObjectを使用する場合、結果を適切な型にキャストする必要があります。 たとえば、

int[] myIntegers = (int[]) myResources.getObject("intList");

Javaプラットフォームでは、ResourceBundleの2つのサブクラスListResourceBundleおよびPropertyResourceBundleが用意されています。これらはリソースを作成するかなり簡単な方法を提供します。 前の例で簡単に示したように、ListResourceBundleはそのリソースをキー/値ペアのリストとして管理します。 PropertyResourceBundleはプロパティ・ファイルを使用してそのリソースを管理します。

ListResourceBundleまたはPropertyResourceBundleでは不十分なときは、独自のResourceBundleサブクラスを書くことができます。 サブクラスでオーバーライドしなければいけないメソッドは2つあります。handleGetObjectおよびgetKeys()

ResourceBundleサブクラスの実装は、複数のスレッドで同時に使用される場合はスレッドセーフである必要があります。 このクラスの非抽象メソッドのデフォルト実装と、直系の既知の具象サブクラスListResourceBundleおよびPropertyResourceBundleのメソッドはスレッドセーフです。

リソース・バンドルと名前付きモジュール

リソース・バンドルは、次の方法でモジュールにデプロイできます:

リソース・バンドルとアプリケーション

リソース・バンドルは、アプリケーションと一緒に同じモジュールにデプロイすることができます。 この場合、リソース・バンドルは、getBundle(String)またはgetBundle(String, Locale)メソッドを呼び出すことによって、モジュール内のコードによってロードされます。

サービス・プロバイダとしてのリソース・バンドル

リソース・バンドルは、1つ以上の「サービス・プロバイダ・モジュール」にデプロイでき、ServiceLoaderを使用して配置できます。 serviceインタフェースまたはクラスを定義する必要があります。 呼び出し元モジュールはサービスを使用することを宣言し、サービス・プロバイダ・モジュールはサービスの実装を提供することを宣言します。 リソース・バンドル・サービスの開発とリソース・バンドル・プロバイダのデプロイについては、ResourceBundleProviderを参照してください。 リソース・バンドルを取得するモジュールは、リソース・バンドル・プロバイダそのものでもかまいません。その場合、このモジュールは、サービス・プロバイダ機構を介してリソース・バンドルの位置を特定するだけです。

「リソース・バンドル・プロバイダ」は、ResourceBundle.Controlの必要性を置き換えるXMLのような任意の形式のリソース・バンドルを提供できます。

他のモジュールとクラスパス内のリソース・バンドル

名前付きモジュールのリソース・バンドルはencapsulatedなので、他のモジュールのコードでは見つけることができません。 名前のないモジュールとクラスパスのリソース・バンドルは、アクセスするすべてのモジュールに対してオープンされています。 リソース・バンドルは、Module.getResourceAsStream(String)で指定されているリソース・カプセル化ルールに従います。

Controlパラメータを指定しないgetBundleファクトリ・メソッドは、「サービス・プロバイダ」からリソース・バンドルを見つけてロードします。 Module.getResourceAsStream(String)をコールして指定されたモジュールから指定されたリソースを検索し、ClassLoader.getResourceAsStream(String)をコールするかのように検索を続行できます。詳細は、getBundleメソッドの仕様を参照してください。 "java.class"または"java.properties"形式のカプセル化されていないリソース・バンドルのみが検索されます。

コール元モジュールが「リソース・バンドル・プロバイダ」の場合、クラス・ローダー検索には戻りません。

スタック(例、JNIアタッチ・スレッドから直接コールされる場合)にコール元フレームがないコンテキストからgetBundleファクトリ・メソッドがコールされる場合、コール元モジュールはデフォルトで「システム・クラス・ローダー」の名前なしモジュールになります。

自動モジュール内のリソース・バンドル

リソース・バンドルの一般的な形式は.propertiesファイル形式です。 通常、.propertiesリソース・バンドルはJARファイルにパッケージ化されています。 リソース・バンドルのみのJARファイルのみを「自動モジュール」として簡単にデプロイできます。 たとえば、JARファイルにエントリ"p/q/Foo_ja.properties"および.classエントリが含まれていて、解決されて自動モジュールとして定義されている場合、このモジュール用のパッケージは派生しません。 これにより、.properties形式のリソース・バンドルが、1つ以上のJARファイルにパッケージ化されます。このバンドルは、同じディレクトリにエントリを含み、自動モジュールとして正常に解決できます。

ResourceBundle.Control

ResourceBundle.Controlクラスは、ResourceBundle.Controlインスタンスを取るgetBundleファクトリ・メソッドがバンドル・ロード処理を実行する際に必要とする情報を提供します。 ユーザー独自のサブクラスを実装すれば、標準以外のリソース・バンドル形式を利用できるようにしたり、検索手順を変更したり、キャッシュ・パラメータを定義したりできます。 詳細については、そのクラスとgetBundleファクトリ・メソッドの説明を参照してください。

ResourceBundle.Controlは、名前のないモジュールにデプロイされたアプリケーション用に設計されています。たとえば、非標準形式のリソース・バンドルをサポートしたり、非伝統的な規則でローカライズされたリソースをパッケージ化することができます。 ResourceBundleProviderは、モジュールに移行するときのResourceBundle.Controlの代わりです。 ResourceBundle.Controlパラメータを受け取るファクトリ・メソッドが呼び出されると、UnsupportedOperationExceptionがスローされます。

ResourceBundle.Controlインスタンスを使用しないgetBundleファクトリ用」メソッド。リソース・バンドル・ロードの「デフォルト動作」は、カスタムのResourceBundleControlProvider実装で変更できます。 指定されたベース名のResourceBundle.Controlをいずれかのプロバイダが提供する場合、そのResourceBundle.ControlはデフォルトResourceBundle.Controlのかわりに使用されます。 同じベース名をサポートするために複数のサービス・プロバイダが存在する場合は、ServiceLoaderから返された最初のサービス・プロバイダが使用されます。 カスタムのResourceBundle.Control実装は、名前付きモジュールでは無視されます。

キャッシュ管理

getBundleファクトリ・メソッドによって作成されたリソース・バンドル・インスタンスはデフォルトでキャッシュされ、ファクトリ・メソッドは同じリソース・バンドル・インスタンス(キャッシュされている場合)を複数回返します。getBundleクライアントは、キャッシュをクリアしたり、有効期間値を使ってキャッシュされたリソース・バンドル・インスタンスの寿命を管理したり、リソース・バンドル・インスタンスをキャッシュしないことを指定したりできます。 詳細については、getBundleファクトリ・メソッドclearCacheResourceBundle.Control.getTimeToLiveおよびResourceBundle.Control.needsReloadの説明を参照してください。

次にあるのはResourceBundleのサブクラスMyResourcesの非常に簡単な例です。このサブクラスは2つのリソースを管理します(サブクラスが多数のリソースを管理する場合は、Mapを使用する)。 「親レベル」のResourceBundleが、(下記のokKeyのように)同じ値を持つ同じキーを扱う場合は、値を提供する必要はありません。
// default (English language, United States)
public class MyResources extends ResourceBundle {
    public Object handleGetObject(String key) {
        if (key.equals("okKey")) {
           return "Ok";
        }
        if (key.equals("cancelKey")) {
           return "Cancel";
        }
        return null;
    }

    public Enumeration<String> getKeys() {
        return Collections.enumeration(keySet());
    }

    // Overrides handleKeySet() so that the getKeys() implementation
    // can rely on the keySet() value.
    protected Set<String> handleKeySet() {
        return new HashSet<String>(Arrays.asList("okKey", "cancelKey"));
    }
}

// German language
public class MyResources_de extends MyResources {
    public Object handleGetObject(String key) {
        // don't need okKey, since parent level handles it.
        if (key.equals("cancelKey")) {
           return "Abbrechen";
        }
        return null;
    }

    protected Set<String> handleKeySet() {
        return new HashSet<String>(Arrays.asList("cancelKey"));
    }
}
ResourceBundleの単一のファミリだけを使用する必要はありません。 たとえば、例外メッセージExceptionResources (ExceptionResources_frExceptionResources_deなど)で1つ、ウィジェットWidgetResource (WidgetResources_frWidgetResources_deなど)で1つというように、好きなようにリソースを分割してバンドルのセットを持つこともできます。
導入されたバージョン:
1.1
関連項目: