java.lang.Object java.util.ResourceBundle
public abstract class ResourceBundle
资源包包含特定于语言环境的对象。当程序需要一个特定于语言环境的资源时(如 String
),程序可以从适合当前用户语言环境的资源包中加载它。使用这种方式,可以编写很大程度上独立于用户语言环境的程序代码,它将资源包中大部分(即便不是全部)特定于语言环境的信息隔离开来。
这使编写的程序可以:
资源包属于这样的系列,其成员共享一个公共的基本名称,但是名称中还有标识其语言环境的其他组件。例如,某个资源包系列的基本名称可能是 "MyResources"。该系列应该有一个默认资源包,其名称与其系列名相同( "MyResources"),如果不支持指定的语言环境,则应该将此资源包用作最后的手段。然后,此系列可根据需要提供特定于语言环境的成员,例如一个名为 "MyResources_de" 的德语资源包。
一个系列中的每个资源包都包含相同的项,但是这些项已经针对该资源包所代表的语言环境进行了翻译。例如,"MyResources" 和 "MyResources_de" 可能有用在取消操作按钮上的 String
。在 "MyResources" 中,String
可能包含 "Cancel",而 "MyResources_de" 中则可能包含 "Abbrechen"。
如果不同的国家/地区有不同的资源,则可以对它们进行限定:例如,"MyResources_de_CH" 包含瑞士 (CH) 中包含德语 (de) 的对象。如果只想修改限定中的某些资源,就可以这样做。
当程序需要特定于语言环境的对象时,它使用 getBundle
方法加载 ResourceBundle
类:
ResourceBundle myResources = ResourceBundle.getBundle("MyResources", currentLocale);
资源包包含键/值对。键唯一地标识了包中特定于语言环境的对象。下面是一个 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"。在上面的示例中,值也是
String
类型,即 "OK" 和 "Cancel",但并非必须如此。值可以是任意对象类型。
可以使用适当的获取方法从资源包中获取某个对象。因为 "OkKey" 和 "CancelKey" 都是字符串,所以应该使用 getString
获取它们:
所有获取方法都需要将键作为参数并返回对象(如果找到的话)。如果未找到对象,则获取方法将抛出button1 = new Button(myResources.getString("OkKey")); button2 = new Button(myResources.getString("CancelKey"));
MissingResourceException
。
除了 getString
之外,ResourceBundle
还提供了获取字符串数组的方法 getStringArray
,以及用于其他任意对象类型的 getObject
方法。使用 getObject
时,必须将结果强制转换为适当的类型。例如:
int[] myIntegers = (int[]) myResources.getObject("intList");
Java 平台提供了两个 ResourceBundle
的子类,即 ListResourceBundle
和 PropertyResourceBundle
,这为创建资源提供了一种相当简单的方式。正如在前面示例中所看到的,ListResourceBundle
以键/值对的列表方式管理其资源。PropertyResourceBundle
则使用一个属性文件来管理其资源。
如果 ListResourceBundle
或 PropertyResourceBundle
无法满足需求,那么可以编写自己的 ResourceBundle
子类。子类必须重写两个方法:handleGetObject
和 getKeys()
。
ResourceBundle.Control
类提供通过带
ResourceBundle.Control
实例的
getBundle
工厂方法执行包加载进程所需的信息。为了启用非标准资源包格式、更改搜索策略或定义缓存参数,可以实现自己的子类。有关细节请参考类和
getBundle
工厂方法的描述。
getBundle
工厂方法创建的资源包实例是默认缓存的,如果资源包实例已经缓存,那么这些工厂方法将多次返回相同的资源包实例。
getBundle
客户端可以清除缓存、使用生存时间值管理已缓存资源包实例的生命周期,或者指定不缓存资源包实例。有关细节请参考
getBundle
工厂方法、
clearCache
、
ResourceBundle.Control.getTimeToLive
和
ResourceBundle.Control.needsReload
的描述。
ResourceBundle
子类示例
MyResources
,它管理两个资源(对于大量的资源,应该使用
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_fr
、
ExceptionResources_de
等)和窗口小部件
WidgetResource
的包集(
WidgetResources_fr
、
WidgetResources_de
等);可以按自己喜欢的方式分解资源。
ListResourceBundle
,
PropertyResourceBundle
,
MissingResourceException
嵌套类摘要 | |
---|---|
static class |
ResourceBundle.Control ResourceBundle.Control 定义一个回调方法集,它在包加载进程中由 ResourceBundle.getBundle 工厂方法调用。 |
字段摘要 | |
---|---|
protected ResourceBundle |
parent 此包的父包。 |
构造方法摘要 | |
---|---|
ResourceBundle() 唯一的构造方法(由子类构造方法调用,通常是隐式的)。 |
方法摘要 | |
---|---|
static void |
clearCache() 从已经使用调用者的类加载器加载的缓存中移除所有资源包。 |
static void |
clearCache(ClassLoader loader) 从已经使用给定类加载器加载的缓存中移除所有资源包。 |
boolean |
containsKey(String key) 确定给定 key 是否包含在此 ResourceBundle 及其父包中。 |
static ResourceBundle |
getBundle(String baseName) 使用指定的基本名称、默认的语言环境和调用者的类加载器获取资源包。 |
static ResourceBundle |
getBundle(String baseName, Locale locale) 使用指定的基本名称、语言环境和调用者的类加载器获取资源包。 |
static ResourceBundle |
getBundle(String baseName, Locale locale, ClassLoader loader) 使用指定的基本名称、语言环境和类加载器获取资源包。 |
static ResourceBundle |
getBundle(String baseName, Locale targetLocale, ClassLoader loader, ResourceBundle.Control control) 使用指定基本名称、目标语言环境、类加载器和控件返回资源包。 |
static ResourceBundle |
getBundle(String baseName, Locale targetLocale, ResourceBundle.Control control) 使用指定基本名称、目标语言环境和控件、调用者的类加载器返回一个资源包。 |
static ResourceBundle |
getBundle(String baseName, ResourceBundle.Control control) 使用指定基本名称、默认语言环境和指定控件返回一个资源包。 |
abstract Enumeration<String> |
getKeys() 返回键的枚举。 |
Locale |
getLocale() 返回此资源包的语言环境。 |
Object |
getObject(String key) 从此资源包或它的某个父包中获取给定键的对象。 |
String |
getString(String key) 从此资源包或它的某个父包中获取给定键的字符串。 |
String[] |
getStringArray(String key) 从此资源包或它的某个父包中获取给定键的字符串数组。 |
protected abstract Object |
handleGetObject(String key) 从此资源包中获取给定键的对象。 |
protected Set<String> |
handleKeySet() 返回只 包含在此 ResourceBundle 中的键的 Set 。 |
Set<String> |
keySet() 返回此 ResourceBundle 及其父包中包含的所有键的 Set 。 |
protected void |
setParent(ResourceBundle parent) 设置此包的父包。 |
从类 java.lang.Object 继承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
字段详细信息 |
---|
protected ResourceBundle parent
getObject
搜索父包。
构造方法详细信息 |
---|
public ResourceBundle()
方法详细信息 |
---|
public final String getString(String key)
(String) getObject
(key)
。
key
- 所需字符串的键
NullPointerException
- 如果
key
为
null
MissingResourceException
- 如果未找到给定键的对象
ClassCastException
- 如果为给定键找到的对象是不是字符串
public final String[] getStringArray(String key)
(String[]) getObject
(key)
。
key
- 所需字符串数组的键
NullPointerException
- 如果
key
为
null
MissingResourceException
- 如果未找到给定键的对象
ClassCastException
- 如果为给定键找到的对象不是字符串数组
public final Object getObject(String key)
handleGetObject
从此资源包中获取对象。如果不成功,并且父资源包不为 null,则调用父包的
getObject
方法。如果仍不成功,则抛出 MissingResourceException。
key
- 所需对象的键
NullPointerException
- 如果
key
为
null
MissingResourceException
- 如果未找到给定键的对象
public Locale getLocale()
protected void setParent(ResourceBundle parent)
getObject
来搜索父包。
parent
- 此包的父包。
public static final ResourceBundle getBundle(String baseName)
getBundle(baseName, Locale.getDefault(), this.getClass().getClassLoader())
,
不同之处在于要使用
ResourceBundle
的安全特权来运行
getClassLoader()
。有关搜索和实例化策略的信息,请参阅
getBundle
。
baseName
- 资源包的基本名称,是一个完全限定类名
NullPointerException
- 如果
baseName
为
null
MissingResourceException
- 如果未找到指定基本名称的资源包
public static final ResourceBundle getBundle(String baseName, ResourceBundle.Control control)
getBundle(baseName, Locale.getDefault(), this.getClass().getClassLoader(), control),不同之处在于要使用
ResourceBundle
的安全特权来运行
getClassLoader()
。有关带
ResourceBundle.Control
的资源包加载进程的完整描述,请参阅
getBundle
。
baseName
- 资源包的基本名称,一个完全限定类名
control
- 为资源包加载进程提供信息的控件
NullPointerException
- 如果
baseName
或
control
为
null
MissingResourceException
- 如果没有找到用于指定基本名称的资源包
IllegalArgumentException
- 如果给定
control
没有正确执行(例如,
control.getCandidateLocales
返回 null。)注意,
control
的验证是根据需要执行的。
public static final ResourceBundle getBundle(String baseName, Locale locale)
getBundle(baseName, locale, this.getClass().getClassLoader())
,
不同之处在于要使用
ResourceBundle
的安全特权来运行
getClassLoader()
。有关搜索和实例化策略的信息,请参阅
getBundle
。
baseName
- 资源包的基本名称,是一个完全限定类名
locale
- 资源包所需的语言环境
NullPointerException
- 如果
baseName
或
locale
为
null
MissingResourceException
- 如果未找到指定基本名称的资源包
public static final ResourceBundle getBundle(String baseName, Locale targetLocale, ResourceBundle.Control control)
getBundle(baseName, targetLocale, this.getClass().getClassLoader(), control),不同之处在于要使用
ResourceBundle
的安全特权来运行
getClassLoader()
。有关带
ResourceBundle.Control
的资源包加载进程的完整描述,请参阅
getBundle
。
baseName
- 资源包的基本名称,一个完全限定类名
targetLocale
- 资源包所需的语言环境
control
- 为资源包加载进程提供信息的控件
locales
中某个
Locale
的资源包
NullPointerException
- 如果
baseName
、
locales
或
control
为
null
MissingResourceException
- 如果在任何
locales
中都无法找到用于指定基本名称的资源包。
IllegalArgumentException
- 如果给定
control
没有正确执行(例如,
control.getCandidateLocales
返回 null。)注意,
control
的验证是根据需要执行的。
public static ResourceBundle getBundle(String baseName, Locale locale, ClassLoader loader)
从概念上讲,getBundle
使用下列策略来搜索并实例化资源包:
getBundle
使用基本名称、指定的语言环境和默认语言环境(从 Locale.getDefault
获得)来生成候选包名称 序列。如果指定语言环境的语言、国家/地区和变量都是空字符串,则基本名称就是唯一的候选包名称。否则,从指定语言环境(language1、country1 和 variant1)和默认语言环境(language2、country2 和 variant2)的属性值生成下列序列:
省略最后部分为空字符串的候选包名称。例如,如果 country1 是一个空字符串,则省略第二个候选包名称。
然后 getBundle
在候选包名称上进行迭代,找到第一个可实例化 为实际资源包的候选包名称。对于每个候选包名称,它都试图创建资源包:
getBundle
将创建此类的一个新实例,并使用它作为结果资源包。 getBundle
尝试搜索属性资源文件。它从候选包名称生成一个路径名,用 "/" 替换所有的 "." 字符,并添加字符串 ".properties"。然后尝试用 ClassLoader.getResource
找到一个具有此名称的“资源”(注意,getResource
获得的“资源”与资源包中的内容没有任何关系,它只是一个数据的容器,如文件)。如果它找到一个“资源”,则会尝试用其内容创建一个新的 PropertyResourceBundle
。如果成功,那么此实例就成为结果资源包。 如果未找到结果资源包,则抛出 MissingResourceException
。
找到了结果资源包后,它的父链 将被实例化。getBundle
在可以获得的候选包名称中进行迭代,获得名称的方法是从结果资源包的包名称中连续移除变量、国家/地区和语言(每次都用前缀 "_")。如上所述,省略最后部分为空字符串的候选包名称。对于每个候选包名称,都尝试实例化一个资源包,如上所述。只要能够成功,就用新的资源包调用先前已实例化资源包的 setParent
方法,除非先前已实例化的资源包已经有非 null 的父包。
getBundle
可以缓存已实例化的资源包,并且可以多次返回相同的资源包实例。
MyResources.class MyResources.properties MyResources_fr.properties MyResources_fr_CH.class MyResources_fr_CH.properties MyResources_en.properties MyResources_es_ES.class所有文件的内容都是有效的(也就是说 ".class" 文件是 ResourceBundle 的公共非抽象子类,".properties" 文件的语法正确)。默认的语言环境是
Locale("en", "GB")
。 使用给出的语言环境参数值调用 getBundle
将实例化取自以下源的资源包:
不使用 MyResources_fr_CH.properties 文件,因为它被 MyResources_fr_CH.class 隐藏了。类似地,MyResources.properties 也被 MyResources.class 隐藏了。
baseName
- 资源包的基本名称,是一个完全限定类名
locale
- 资源包所需的语言环境
loader
- 加载资源包的类加载器
NullPointerException
- 如果
baseName
、
locale
或
loader
为
null
MissingResourceException
- 如果未找到指定基本名称的资源包
public static ResourceBundle getBundle(String baseName, Locale targetLocale, ClassLoader loader, ResourceBundle.Control control)
control
参数的 getBundle
工厂方法不同,给定
control
指定查找和实例化资源包的方式。从概念上说,具有给定
control
的包加载进程是按以下步骤执行的。
baseName
、targetLocale
和 loader
查找资源包。如果在缓存中找到所请求的资源包实例,并且该实例及其所有父实例的生存时间都已经到期,则向调用者返回该实例。否则,此工厂方法继续进行以下加载进程。control.getFormats
方法获取生成包名称或资源名称的资源包格式。字符串 "java.class"
和 "java.properties"
分别指定基于类和基于属性的资源包。其他以 "java."
开头的字符串被保留,供以后扩展使用,不必将它们用于应用程序定义的格式。其他字符串指定应用程序定义的格式。control.getCandidateLocales
方法获取用于已搜索到的资源包的候选 Locale
列表。control.newBundle
方法实例化针对基本包名称、候选语言环境和某种格式的 ResourceBundle
。(参考下方关于缓存查找的注释。)此步骤在所有候选语言环境和格式上进行迭代,直到 newBundle
方法返回一个 ResourceBundle
实例,或者该迭代已经用完了所有的组合。例如,如果候选语言环境是 Locale("de", "DE")
、Locale("de")
和 Locale("")
,而格式是 "java.class"
和 "java.properties"
,那么以下是用来调用 control.newBundle
的语言环境和格式组合的序列。
语言环境 |
格式 |
Locale("de", "DE") |
java.class |
Locale("de", "DE") | java.properties |
Locale("de") | java.class |
Locale("de") | java.properties |
Locale("") |
java.class |
Locale("") | java.properties |
Locale("")
的包),以及只包含 Locale("")
的候选语言环境列表,则向调用者返回该包。如果已经找到作为基本包的包,但候选语言环境列表包含 Locale("") 之外的语言环境,则暂时搁置该包并前进到步骤 6。如果找到一个不是基本包的包,则前进到步骤 7。control.getFallbackLocale
方法获取一个回退语言环境(当前目标语言环境的替代),以尝试进一步寻找资源包。如果该方法返回一个非 null 语言环境,那么该语言环境将变成下一个目标语言环境,并且加载进程将从步骤 3 开始。否则,如果找到一个基本包并在前面的步骤 5 中暂时被搁置,那么现在要将该语言环境返回给调用者。否则抛出 MissingResourceException。在进行上述资源包加载进程期间,此工厂方法将在调用 control.newBundle
方法之前查找缓存。如果在该缓存中找到的资源包的生存时间已到期,则该工厂方法将调用 control.needsReload
方法确定是否需要重载资源包。如果需要重载,则该工厂方法将调用 control.newBundle
重载资源包。如果 control.newBundle
返回 null
,则该工厂方法将在缓存中放一个伪资源包,以此作为不存在资源包的标记,从而避免后续请求所带来的查找开销。这类伪资源包同样受到 control
所指定的到期时间控制。
所有已加载的资源包都是在默认情况下被缓存的。有关细节请参阅 control.getTimeToLive
。
以下是带有默认 ResourceBundle.Control
实现的包加载进程的示例。
条件:
foo.bar.Messages
Locale
:Locale.ITALY
Locale
:Locale.FRENCH
foo/bar/Messages_fr.properties
和 foo/bar/Messages.properties
首先,getBundle
试图按以下顺序加载资源包。
foo.bar.Messages_it_IT
foo/bar/Messages_it_IT.properties
foo.bar.Messages_it
foo/bar/Messages_it.properties
foo.bar.Messages
foo/bar/Messages.properties
此时,getBundle
找到一个 foo/bar/Messages.properties
,该包被搁置,因为它不是一个基本包。getBundle
调用返回 Locale.FRENCH
的 control.getFallbackLocale("foo.bar.Messages", Locale.ITALY)
。接着,getBundle
试图按以下顺序加载一个包。
foo.bar.Messages_fr
foo/bar/Messages_fr.properties
foo.bar.Messages
foo/bar/Messages.properties
getBundle
查找 foo/bar/Messages_fr.properties
并创建一个 ResourceBundle
实例。然后,getBundle
根据候选语言环境列表设置其父链。在该列表中只有 foo/bar/Messages.properties
,并且 getBundle
创建一个 ResourceBundle
实例,该实例成为用于 foo/bar/Messages_fr.properties
的实例的父实例。
baseName
- 资源包的基本名称,一个完全限定类名
targetLocale
- 资源包所需的语言环境
loader
- 加载资源包的类加载器
control
- 为资源包加载进程提供信息的控件
NullPointerException
- 如果
baseName
、
targetLocale
、
loader
或
control
为
null
MissingResourceException
- 如果没有找到用于指定基本名称的资源包
IllegalArgumentException
- 如果给定
control
没有正确执行(例如,
control.getCandidateLocales
返回 null。)注意,
control
的验证是根据需要执行的。
public static final void clearCache()
ResourceBundle.Control.getTimeToLive(String,Locale)
public static final void clearCache(ClassLoader loader)
loader
- 类加载器
NullPointerException
- 如果
loader
为 null
ResourceBundle.Control.getTimeToLive(String,Locale)
protected abstract Object handleGetObject(String key)
key
- 所需对象的键
NullPointerException
- 如果
key
为
null
public abstract Enumeration<String> getKeys()
ResourceBundle
及其父包中所包含键的
Enumeration
。
public boolean containsKey(String key)
key
是否包含在此
ResourceBundle
及其父包中。