Java ResourceBundle

时间:2020-01-09 10:35:36  来源:igfitidea点击:

Java ResourceBundle类java.util.ResourceBundle用于存储对语言环境敏感的文本和组件。例如,应用程序内部使用的文本标签可能需要更改,具体取决于当前使用应用程序的用户的语言。因此,文本标签被称为对用户区域敏感。顺便说一下,用户的语言环境由Java Locale类表示。本文将仔细研究ResourceBundle类及其子类。

ResourceBundle类层次结构

" ResourceBundle"类具有两个子类,分别称为" PropertyResourceBundle"和" ListResourceBundle"。

" PropertyResourceBundle"类将本地化的文本存储在标准Java属性文件中。我的Java属性教程中解释了这些文件的格式。

我们不会直接与这两个子类进行交互。所有交互都通过ResourceBundle类进行。

创建一个ResourceBundle

我们可以这样创建ResourceBundle实例:

Locale locale = new Locale("en", "US");

ResourceBundle labels = ResourceBundle.getBundle("i18n.MyBundle", locale);

System.out.println(labels.getString("label1"));

首先,我们需要一个Locale实例。然后,将该Locale实例以及要加载的资源包的名称传递给ResourceBundle.getBundle()方法。最后,我们可以通过不同的getString()getObject()等方法访问ResourceBundle中的本地化值。

我们实际上从未创建过ResourceBundle实例,而是其两个子类之一的实例。两者都是使用上述工厂方法创建的。首先,ResourceBundle类将寻找ListResourceBundle,然后寻找PropertyResourceBundle。它通过首先将请求的资源束的名称(getBundle()方法中的第一个参数)与ListResourceBundle的类名称进行匹配(如果找不到),与属性文件资源束进行匹配。

以下各节将更详细地介绍ListResourceBundle和PropertyResourceBundle。

属性文件作为ResourceBundle

我们可以使用标准属性文件来存储本地化的文本。我们可以通过ResourceBundle类加载这些属性。这是一个例子:

Locale locale = new Locale("en", "US");

ResourceBundle labels = ResourceBundle.getBundle("i18n.MyBundle", locale);

System.out.println(labels.getString("label1"));

为了使该示例正常工作,我们应该在名为i18n的Java包中放入一个名为MyBundle.properties的标准Java属性文件。运行上述代码时,请确保该属性文件在类路径上可用,这意味着该属性文件应位于应用程序的类之间以及在i18n软件包中。

资源束的名称类似于类名称。因此," i18n.MyBundle"表示包(目录)" i18n"中名为" MyBundle.properties"的属性文件。

这是属性文件内容的示例:

label1 = Label 1 is done!
label2 = Label 2 is through!

与Java属性文件的标准一样,它是键和值对的列表。键位于=的左侧,值位于右侧。该值是我们应本地化的内容,而不是键。

不同属性文件中的不同语言

为了提供不同语言的字符串,请为每种语言创建一个属性文件,并用下划线(_)和语言代码作为后缀。例如:

MyBundle.properties
MyBundle_da.properties
MyBundle_de.properties
MyBundle_fr.properties

所有这些文件应位于同一包(目录)中。

没有语言后缀的文件(例如," MyBundle.properties")是默认属性文件。如果没有属性文件可用于传递给ResourceBundle.getBundle()方法的语言(语言环境),并且系统没有设置默认语言环境(例如,德语计算机将德语语言环境作为默认设置),读取文件并将其作为" ResourceBundle"返回。

具有语言代码后缀的其他属性文件包含相同的键,但具有不同语言的值。因此,丹麦属性文件可能如下所示:

label1 = Label 1 er klar!
label2 = Label 2 er igennem!

类为ResourceBundle

我们还可以使用一组类来包含资源。使用类,我们不仅可以使用字符串值。

与属性文件一样,我们可以创建一组具有捆绑包基本名称和语言后缀的类。例如:

i18n.MyClassBundle
i18n.MyClassBundle_da
i18n.MyClassBundle_en
i18n.MyClassBundle_de

这是默认捆绑软件类文件的示例实现:

package i18n;

import java.util.ListResourceBundle;

public class MyClassBundle extends ListResourceBundle {

    @Override
    protected Object[][] getContents() {
        return contents;
    }

    private Object[][] contents = {
            { "price"   , new Double(10.00) },
            { "currency", "EUR" },
    };
}

这是丹麦语资源包的实现:

public class MyClassBundle_da extends ListResourceBundle {

    @Override
    protected Object[][] getContents() {
        return contents;
    }

    private Object[][] contents = {
            { "price"   , new Double(75.00) },
            { "currency", "DKK" },
    };

}

注意" contents"数组。它由键和值的二维数组组成。因此," price"和" currency"是键,它们右边的值是本地化值。这两个示例包含两种不同货币的价格。

我们获得ListProsourceBundle的实例的方式与获得PropertyResourceBundle的实例的方式相同。以下是两个获取丹麦语默认ResourceBundleResourceBundle的实例的示例:

Locale locale = new Locale("de", "DE"); //no bundle for German -> default
ResourceBundle bundle = ResourceBundle.getBundle("i18n.MyClassBundle", locale);

System.out.println("price   : " + bundle.getObject("price"));
System.out.println("currency: " + bundle.getObject("currency"));

locale = new Locale("da", "DK");
bundle = ResourceBundle.getBundle("i18n.MyClassBundle", locale);

System.out.println("price   : " + bundle.getObject("price"));
System.out.println("currency: " + bundle.getObject("currency"));

此代码输出的输出为:

price   : 10.0
currency: EUR
price   : 75.0
currency: DKK

从默认的" ResourceBundle"获得的价格在" EUR"中列出,从丹麦的" ResourceBundle"获得的价格在" DKK"中列出。

从ResourceBundle获取价值

获得ResourceBundle实例后,我们可以使用以下方法之一从其中获取本地化的值:

getObject(String key);
getString(String key);
getStringArray(String key);

我们还可以使用keySet()方法获取ResourceBundle中包含的所有键的集合,如下所示:

Set<String> keys = bundle.keySet();

其他ResourceBundle方法

ResourceBundle类还有其他一些方法(例如getLocale())。请查看JavaDoc,以获取有关这些方法的更多信息。