JavaTM Platform
Standard Ed. 6

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。在 "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 的子类,即 ListResourceBundlePropertyResourceBundle,这为创建资源提供了一种相当简单的方式。正如在前面示例中所看到的,ListResourceBundle 以键/值对的列表方式管理其资源。PropertyResourceBundle 则使用一个属性文件来管理其资源。

如果 ListResourceBundlePropertyResourceBundle 无法满足需求,那么可以编写自己的 ResourceBundle 子类。子类必须重写两个方法:handleGetObjectgetKeys()

ResourceBundle.Control

ResourceBundle.Control 类提供通过带 ResourceBundle.Control 实例的 getBundle 工厂方法执行包加载进程所需的信息。为了启用非标准资源包格式、更改搜索策略或定义缓存参数,可以实现自己的子类。有关细节请参考类和 getBundle 工厂方法的描述。

缓存管理

getBundle 工厂方法创建的资源包实例是默认缓存的,如果资源包实例已经缓存,那么这些工厂方法将多次返回相同的资源包实例。getBundle 客户端可以清除缓存、使用生存时间值管理已缓存资源包实例的生命周期,或者指定不缓存资源包实例。有关细节请参考getBundle 工厂方法clearCacheResourceBundle.Control.getTimeToLiveResourceBundle.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_frExceptionResources_de 等)和窗口小部件 WidgetResource 的包集(WidgetResources_frWidgetResources_de 等);可以按自己喜欢的方式分解资源。

从以下版本开始:
JDK1.1
另请参见:
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
 

字段详细信息

parent

protected ResourceBundle parent
此包的父包。当此包不包含特定资源时,由 getObject 搜索父包。

构造方法详细信息

ResourceBundle

public ResourceBundle()
唯一的构造方法(由子类构造方法调用,通常是隐式的)。

方法详细信息

getString

public final String getString(String key)
从此资源包或它的某个父包中获取给定键的字符串。调用此方法等同于调用
(String) getObject(key)

参数:
key - 所需字符串的键
返回:
给定键的字符串
抛出:
NullPointerException - 如果 keynull
MissingResourceException - 如果未找到给定键的对象
ClassCastException - 如果为给定键找到的对象是不是字符串

getStringArray

public final String[] getStringArray(String key)
从此资源包或它的某个父包中获取给定键的字符串数组。调用此方法等同于调用
(String[]) getObject(key)

参数:
key - 所需字符串数组的键
返回:
给定键的字符串数组
抛出:
NullPointerException - 如果 keynull
MissingResourceException - 如果未找到给定键的对象
ClassCastException - 如果为给定键找到的对象不是字符串数组

getObject

public final Object getObject(String key)
从此资源包或它的某个父包中获取给定键的对象。此方法首先尝试使用 handleGetObject 从此资源包中获取对象。如果不成功,并且父资源包不为 null,则调用父包的 getObject 方法。如果仍不成功,则抛出 MissingResourceException。

参数:
key - 所需对象的键
返回:
给定键的对象
抛出:
NullPointerException - 如果 keynull
MissingResourceException - 如果未找到给定键的对象

getLocale

public Locale getLocale()
返回此资源包的语言环境。调用 getBundle() 后可使用此方法来确定返回的资源包是真正对应于所请求的语言环境,还是只是一个回退。

返回:
此资源包的语言环境

setParent

protected void setParent(ResourceBundle parent)
设置此包的父包。当此包不包含特定的资源时,通过 getObject 来搜索父包。

参数:
parent - 此包的父包。

getBundle

public static final ResourceBundle getBundle(String baseName)
使用指定的基本名称、默认的语言环境和调用者的类加载器获取资源包。调用此方法等同于调用
getBundle(baseName, Locale.getDefault(), this.getClass().getClassLoader())
不同之处在于要使用 ResourceBundle 的安全特权来运行 getClassLoader()。有关搜索和实例化策略的信息,请参阅 getBundle

参数:
baseName - 资源包的基本名称,是一个完全限定类名
返回:
具有给定基本名称和默认语言环境的资源包
抛出:
NullPointerException - 如果 baseNamenull
MissingResourceException - 如果未找到指定基本名称的资源包

getBundle

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 - 如果 baseNamecontrolnull
MissingResourceException - 如果没有找到用于指定基本名称的资源包
IllegalArgumentException - 如果给定 control 没有正确执行(例如,control.getCandidateLocales 返回 null。)注意,control 的验证是根据需要执行的。
从以下版本开始:
1.6

getBundle

public static final ResourceBundle getBundle(String baseName,
                                             Locale locale)
使用指定的基本名称、语言环境和调用者的类加载器获取资源包。调用此方法等同于调用
getBundle(baseName, locale, this.getClass().getClassLoader())
不同之处在于要使用 ResourceBundle 的安全特权来运行 getClassLoader()。有关搜索和实例化策略的信息,请参阅 getBundle

参数:
baseName - 资源包的基本名称,是一个完全限定类名
locale - 资源包所需的语言环境
返回:
具有给定基本名称和语言环境的资源包
抛出:
NullPointerException - 如果 baseNamelocalenull
MissingResourceException - 如果未找到指定基本名称的资源包

getBundle

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 - 如果 baseNamelocalescontrolnull
MissingResourceException - 如果在任何 locales 中都无法找到用于指定基本名称的资源包。
IllegalArgumentException - 如果给定 control 没有正确执行(例如,control.getCandidateLocales 返回 null。)注意,control 的验证是根据需要执行的。
从以下版本开始:
1.6

getBundle

public static ResourceBundle getBundle(String baseName,
                                       Locale locale,
                                       ClassLoader loader)
使用指定的基本名称、语言环境和类加载器获取资源包。

从概念上讲,getBundle 使用下列策略来搜索并实例化资源包:

getBundle 使用基本名称、指定的语言环境和默认语言环境(从 Locale.getDefault 获得)来生成候选包名称 序列。如果指定语言环境的语言、国家/地区和变量都是空字符串,则基本名称就是唯一的候选包名称。否则,从指定语言环境(language1、country1 和 variant1)和默认语言环境(language2、country2 和 variant2)的属性值生成下列序列:

省略最后部分为空字符串的候选包名称。例如,如果 country1 是一个空字符串,则省略第二个候选包名称。

然后 getBundle 在候选包名称上进行迭代,找到第一个可实例化 为实际资源包的候选包名称。对于每个候选包名称,它都试图创建资源包:

如果未找到结果资源包,则抛出 MissingResourceException

找到了结果资源包后,它的父链 将被实例化。getBundle 在可以获得的候选包名称中进行迭代,获得名称的方法是从结果资源包的包名称中连续移除变量、国家/地区和语言(每次都用前缀 "_")。如上所述,省略最后部分为空字符串的候选包名称。对于每个候选包名称,都尝试实例化一个资源包,如上所述。只要能够成功,就用新的资源包调用先前已实例化资源包的 setParent 方法,除非先前已实例化的资源包已经有非 null 的父包。

getBundle 可以缓存已实例化的资源包,并且可以多次返回相同的资源包实例。

baseName 参数应该是一个完全限定类名。但是,为了与早期的版本兼容,Sun 的 Java SE Runtime Environment 并不对此进行检查,所以可通过指定路径名(使用 "/")而不是完全限定类名(使用 ".")来访问 PropertyResourceBundle

示例:
提供了下面的类和属性文件:

     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 将实例化取自以下源的资源包:

  • Locale("fr", "CH"):结果 MyResources_fr_CH.class、父 MyResources_fr.properties、父 MyResources.class
  • Locale("fr", "FR"):结果 MyResources_fr.properties、父 MyResources.class
  • Locale("de", "DE"):结果 MyResources_en.properties、父 MyResources.class
  • Locale("en", "US"):结果 MyResources_en.properties、父 MyResources.class
  • Locale("es", "ES"):结果 MyResources_es_ES.class、父 MyResources.class

不使用 MyResources_fr_CH.properties 文件,因为它被 MyResources_fr_CH.class 隐藏了。类似地,MyResources.properties 也被 MyResources.class 隐藏了。

参数:
baseName - 资源包的基本名称,是一个完全限定类名
locale - 资源包所需的语言环境
loader - 加载资源包的类加载器
返回:
用于给定基本名称和语言环境的资源包
抛出:
NullPointerException - 如果 baseNamelocaleloadernull
MissingResourceException - 如果未找到指定基本名称的资源包
从以下版本开始:
1.2

getBundle

public static ResourceBundle getBundle(String baseName,
                                       Locale targetLocale,
                                       ClassLoader loader,
                                       ResourceBundle.Control control)
使用指定基本名称、目标语言环境、类加载器和控件返回资源包。与 不带 control 参数的 getBundle 工厂方法不同,给定 control 指定查找和实例化资源包的方式。从概念上说,具有给定 control 的包加载进程是按以下步骤执行的。

  1. 此工厂方法在缓存中为指定 baseNametargetLocaleloader 查找资源包。如果在缓存中找到所请求的资源包实例,并且该实例及其所有父实例的生存时间都已经到期,则向调用者返回该实例。否则,此工厂方法继续进行以下加载进程。
  2. 调用 control.getFormats 方法获取生成包名称或资源名称的资源包格式。字符串 "java.class""java.properties" 分别指定基于类和基于属性的资源包。其他以 "java." 开头的字符串被保留,供以后扩展使用,不必将它们用于应用程序定义的格式。其他字符串指定应用程序定义的格式。
  3. 可以调用带有目标语言环境的 control.getCandidateLocales 方法获取用于已搜索到的资源包的候选 Locale 列表。
  4. 可以调用 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
  5. 如果前面的步骤未找到资源包,则前进到步骤 6。如果已经找到用作基本包的包(Locale("") 的包),以及只包含 Locale("") 的候选语言环境列表,则向调用者返回该包。如果已经找到作为基本包的包,但候选语言环境列表包含 Locale("") 之外的语言环境,则暂时搁置该包并前进到步骤 6。如果找到一个不是基本包的包,则前进到步骤 7。
  6. 可调用 control.getFallbackLocale 方法获取一个回退语言环境(当前目标语言环境的替代),以尝试进一步寻找资源包。如果该方法返回一个非 null 语言环境,那么该语言环境将变成下一个目标语言环境,并且加载进程将从步骤 3 开始。否则,如果找到一个基本包并在前面的步骤 5 中暂时被搁置,那么现在要将该语言环境返回给调用者。否则抛出 MissingResourceException。
  7. 此时,我们已经找到一个不是基本包的包。如果此包在其实例化期间设置其父链,则将此包返回给调用者。否则,根据从中找到此包的候选语言环境列表,将此包的父链实例化。最后将该包返回给调用者。

在进行上述资源包加载进程期间,此工厂方法将在调用 control.newBundle 方法之前查找缓存。如果在该缓存中找到的资源包的生存时间已到期,则该工厂方法将调用 control.needsReload 方法确定是否需要重载资源包。如果需要重载,则该工厂方法将调用 control.newBundle 重载资源包。如果 control.newBundle 返回 null,则该工厂方法将在缓存中放一个伪资源包,以此作为不存在资源包的标记,从而避免后续请求所带来的查找开销。这类伪资源包同样受到 control 所指定的到期时间控制。

所有已加载的资源包都是在默认情况下被缓存的。有关细节请参阅 control.getTimeToLive

以下是带有默认 ResourceBundle.Control 实现的包加载进程的示例。

条件:

首先,getBundle 试图按以下顺序加载资源包。

此时,getBundle 找到一个 foo/bar/Messages.properties,该包被搁置,因为它不是一个基本包。getBundle 调用返回 Locale.FRENCHcontrol.getFallbackLocale("foo.bar.Messages", Locale.ITALY)。接着,getBundle 试图按以下顺序加载一个包。

getBundle 查找 foo/bar/Messages_fr.properties 并创建一个 ResourceBundle 实例。然后,getBundle 根据候选语言环境列表设置其父链。在该列表中只有 foo/bar/Messages.properties,并且 getBundle 创建一个 ResourceBundle 实例,该实例成为用于 foo/bar/Messages_fr.properties 的实例的父实例。

参数:
baseName - 资源包的基本名称,一个完全限定类名
targetLocale - 资源包所需的语言环境
loader - 加载资源包的类加载器
control - 为资源包加载进程提供信息的控件
返回:
用于给定基本名称和语言环境的资源包
抛出:
NullPointerException - 如果 baseNametargetLocaleloadercontrolnull
MissingResourceException - 如果没有找到用于指定基本名称的资源包
IllegalArgumentException - 如果给定 control 没有正确执行(例如,control.getCandidateLocales 返回 null。)注意,control 的验证是根据需要执行的。
从以下版本开始:
1.6

clearCache

public static final void clearCache()
从已经使用调用者的类加载器加载的缓存中移除所有资源包。

从以下版本开始:
1.6
另请参见:
ResourceBundle.Control.getTimeToLive(String,Locale)

clearCache

public static final void clearCache(ClassLoader loader)
从已经使用给定类加载器加载的缓存中移除所有资源包。

参数:
loader - 类加载器
抛出:
NullPointerException - 如果 loader 为 null
从以下版本开始:
1.6
另请参见:
ResourceBundle.Control.getTimeToLive(String,Locale)

handleGetObject

protected abstract Object handleGetObject(String key)
从此资源包中获取给定键的对象。如果此资源包未包含给定键的对象,则返回 null。

参数:
key - 所需对象的键
返回:
给定键的对象,或者返回 null
抛出:
NullPointerException - 如果 keynull

getKeys

public abstract Enumeration<String> getKeys()
返回键的枚举。

返回:
ResourceBundle 及其父包中所包含键的 Enumeration

containsKey

public boolean containsKey(String key)
确定给定 key 是否包含在此 ResourceBundle 及其父包中。

参数:
key - 资源 key
返回:
如果给定 key 包含在此 ResourceBundle 或其父包中,则返回 true;否则返回 false
抛出:
NullPointerException - 如果 keynull
从以下版本开始:
1.6

keySet

public Set<String> keySet()
返回此 ResourceBundle 及其父包中包含的所有键的 Set

返回:
Set 及其父包中包含的所有键的 Set
从以下版本开始:
1.6

handleKeySet

protected Set<String> handleKeySet()
返回 包含在此 ResourceBundle 中的键的 Set

默认实现返回 getKeys 方法返回的键的 Set,那些 handleGetObject 方法返回 null 的键除外。创建 Set 后,该值就被保存在此 ResourceBundle 中,以避免在下次调用中产生相同的 Set。可在子类实现中重写此方法,以便更快地进行处理。

返回:
只包含于此 ResourceBundle 中的键的 Set
从以下版本开始:
1.6

JavaTM Platform
Standard Ed. 6

提交错误或意见
有关更多的 API 参考资料和开发人员文档,请参阅 Java SE 开发人员文档。该文档包含更详细的、面向开发人员的描述,以及总体概述、术语定义、使用技巧和工作代码示例。

版权所有 2007 Sun Microsystems, Inc. 保留所有权利。 请遵守许可证条款。另请参阅文档重新分发政策