Java ResourceBundle
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的实例的方式相同。以下是两个获取丹麦语默认ResourceBundle
和ResourceBundle
的实例的示例:
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,以获取有关这些方法的更多信息。