Module java.base
Package java.util

Class 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)对象。如果您只想修改特定资源的一些内容,您可以这样做。

当您的程序需要特定于区域设置的对象时,它使用ResourceBundle类通过getBundle方法加载:

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

资源包含有键/值对。键唯一标识资源包中的特定于区域设置的对象。以下是一个包含两个键/值对的ListResourceBundle示例:

public class MyResources extends ListResourceBundle {
    protected Object[][] getContents() {
        return new Object[][] {
            // 本地化每个数组的第二个字符串(例如,"OK")
            {"OkKey", "OK"},
            {"CancelKey", "Cancel"},
            // 本地化材料结束
       };
    }
}
键始终是String。在此示例中,键是"OkKey"和"CancelKey"。在上面的示例中,值也是String - "OK"和"Cancel" - 但不一定是。值可以是任何类型的对象。

您可以使用适当的getter方法从资源包中检索对象。因为"OkKey"和"CancelKey"都是字符串,您将使用getString来检索它们:

button1 = new Button(myResources.getString("OkKey"));
button2 = new Button(myResources.getString("CancelKey"));
所有的getter方法都需要键作为参数,并在找到对象时返回该对象。如果未找到对象,getter方法将抛出一个MissingResourceException

除了getStringResourceBundle还提供了一个用于获取字符串数组的方法getStringArray,以及一个用于获取任何其他类型对象的通用getObject方法。当使用getObject时,您需要将结果转换为适当的类型。例如:

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

Java平台提供了ResourceBundle的两个子类,ListResourceBundlePropertyResourceBundle,它们提供了一种相当简单的创建资源的方式。正如您在前面的示例中简要看到的,ListResourceBundle将其资源管理为键/值对列表。PropertyResourceBundle使用属性文件来管理其资源。

如果ListResourceBundlePropertyResourceBundle不符合您的需求,您可以编写自己的ResourceBundle子类。您的子类必须覆盖两个方法:handleGetObjectgetKeys()

ResourceBundle子类的实现在同时被多个线程使用时必须是线程安全的。该类中非抽象方法的默认实现,以及直接已知的具体子类ListResourceBundlePropertyResourceBundle中的方法都是线程安全的。

资源包和命名模块

资源包可以以以下方式部署在模块中:

资源包与应用程序一起

资源包可以与应用程序一起在同一个模块中部署。在这种情况下,资源包通过调用getBundle(String)getBundle(String, Locale)方法由模块中的代码加载。

资源包作为服务提供者

资源包可以部署在一个或多个服务提供者模块中,并且可以使用ServiceLoader进行定位。必须定义一个服务接口或类。调用模块声明它使用该服务,服务提供者模块声明它们提供服务的实现。请参考ResourceBundleProvider以开发资源包服务和部署资源包提供者。获取资源包的模块可以是资源包提供者本身;在这种情况下,该模块仅通过服务提供者机制定位资源包。

一个资源包提供者可以提供任何格式的资源包,例如XML,这样就取代了ResourceBundle.Control的需要。

其他模块和类路径中的资源包

命名模块中的资源包可能被封装,以便其他模块中的代码无法定位。未命名模块和类路径中的资源包对于任何模块都是开放的。资源包遵循在Module.getResourceAsStream(String)中指定的资源封装规则。

没有Control参数的getBundle工厂方法会从服务提供者中定位和加载资源包。它可能会继续搜索,就像调用Module.getResourceAsStream(String)以查找给定模块的命名资源并调用ClassLoader.getResourceAsStream(String)一样;有关详细信息,请参阅getBundle方法的规范。只会搜索非封装的资源包的"java.class"或"java.properties"格式。

如果调用模块是一个资源包提供者,它不会回退到类加载器搜索。

在没有调用者帧的情况下调用getBundle工厂方法的情况下(例如,直接从JNI附加线程调用时),调用者模块默认为系统类加载器的未命名模块。

自动模块中的资源包

资源包的一种常见格式是.properties文件格式。通常,.properties资源包被打包在一个JAR文件中。只包含资源包的JAR文件可以作为一个自动模块轻松部署。例如,如果JAR文件包含条目"p/q/Foo_ja.properties"而没有.class条目,当解析并定义为自动模块时,此模块不会派生任何包。这允许在一个或多个JAR文件中打包的.properties格式的资源包包含在同一目录中的条目,并且可以成功解析为自动模块。

ResourceBundle.Control

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

ResourceBundle.Control是为部署在未命名模块中的应用程序设计的,例如支持非标准格式的资源包或在非传统约定中打包本地化资源。当迁移到模块时,ResourceBundleProviderResourceBundle.Control的替代品。当调用带有ResourceBundle.Control参数的工厂方法时,将抛出UnsupportedOperationException

对于不带ResourceBundle.Control实例的getBundle工厂方法,可以使用自定义的ResourceBundleControlProvider实现来修改其资源包加载的默认行为。如果任何提供程序为给定基本名称提供了ResourceBundle.Control,则将使用该ResourceBundle.Control而不是默认的ResourceBundle.Control。如果有多个支持相同基本名称的服务提供程序,则将使用从ServiceLoader返回的第一个。命名模块将忽略自定义的ResourceBundle.Control实现。

缓存管理

getBundle工厂方法创建的资源包实例默认情况下会被缓存,如果已经被缓存,则工厂方法会多次返回相同的资源包实例。getBundle客户端可以清除缓存,使用存活时间值管理缓存的资源包实例的生命周期,或指定不缓存资源包实例。有关详细信息,请参阅getBundle工厂方法clearCacheResourceBundle.Control.getTimeToLiveResourceBundle.Control.needsReload

示例

以下是一个非常简单的ResourceBundle子类MyResources的示例,管理两个资源(对于更多资源,您可能会使用Map)。请注意,如果“父级”ResourceBundle处理相同键具有相同值(如下面的okKey),则无需提供值。
// 默认(英语,美国)
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());
    }

    // 重写handleKeySet(),以便getKeys()实现可以依赖于keySet()值。
    protected Set<String> handleKeySet() {
        return new HashSet<String>(Arrays.asList("okKey", "cancelKey"));
    }
}

// 德语
public class MyResources_de extends MyResources {
    public Object handleGetObject(String key) {
        // 不需要okKey,因为父级处理它。
        if (key.equals("cancelKey")) {
           return "Abbrechen";
        }
        return null;
    }

    protected Set<String> handleKeySet() {
        return new HashSet<String>(Arrays.asList("cancelKey"));
    }
}
您不必局限于使用单个ResourceBundle系列。例如,您可以为异常消息创建一组资源包,ExceptionResourcesExceptionResources_frExceptionResources_de,...),并为小部件创建另一个,WidgetResourceWidgetResources_frWidgetResources_de,...);按照您喜欢的方式拆分资源。
自1.1版本开始:
参见:
  • Field Details

    • parent

      protected ResourceBundle parent
      此bundle的父bundle。当此bundle不包含特定资源时,getObject将搜索父bundle。
  • Constructor Details

    • ResourceBundle

      public ResourceBundle()
      唯一的构造函数。(通常由子类构造函数隐式调用。)
  • Method Details

    • getBaseBundleName

      public String getBaseBundleName()
      返回此bundle的基本名称,如果已知,则返回null。如果不为null,则这是在加载资源bundle时传递给ResourceBundle.getBundle(...)方法的baseName参数的值。
      返回:
      资源bundle的基本名称,由ResourceBundle.getBundle(...)方法提供和期望的名称。
      自1.8版本开始:
      参见:
    • getString

      public final String getString(String key)
      从此资源bundle或其父bundle中获取给定键的字符串。调用此方法等效于调用
          (String[]) getObject(key);
      
      参数:
      key - 所需字符串的键
      返回:
      给定键的字符串
      抛出:
      NullPointerException - 如果keynull
      MissingResourceException - 如果找不到给定键的对象
      ClassCastException - 如果找到的给定键的对象不是字符串
    • getStringArray

      public final String[] getStringArray(String key)
      从此资源bundle或其父bundle中获取给定键的字符串数组。调用此方法等效于调用
          (String[]) getObject(key);
      
      参数:
      key - 所需字符串数组的键
      返回:
      给定键的字符串数组
      抛出:
      NullPointerException - 如果keynull
      MissingResourceException - 如果找不到给定键的对象
      ClassCastException - 如果找到的给定键的对象不是字符串数组
    • getObject

      public final Object getObject(String key)
      从此资源bundle或其父bundle中获取给定键的对象。此方法首先尝试使用handleGetObject从此资源bundle获取对象。如果不成功,并且父资源bundle不为null,则调用父级的getObject方法。如果仍然不成功,则抛出MissingResourceException。
      参数:
      key - 所需对象的键
      返回:
      给定键的对象
      抛出:
      NullPointerException - 如果keynull
      MissingResourceException - 如果找不到给定键的对象
    • getLocale

      public Locale getLocale()
      返回此资源bundle的区域设置。可以在调用getBundle()后使用此方法,以确定返回的资源bundle是否真正对应于请求的区域设置或是一个回退。
      返回:
      此资源bundle的区域设置
    • setParent

      protected void setParent(ResourceBundle parent)
      设置此bundle的父bundle。当此bundle不包含特定资源时,getObject将搜索父bundle。
      参数:
      parent - 此bundle的父bundle。
    • getBundle

      public static final ResourceBundle getBundle(String baseName)
      使用指定的基本名称、默认区域设置和调用者模块获取资源bundle。调用此方法等效于调用
          getBundle(baseName, Locale.getDefault(), callerModule);
      
      参数:
      baseName - 资源bundle的基本名称,一个完全限定的类名
      返回:
      给定基本名称和默认区域设置的资源bundle
      抛出:
      NullPointerException - 如果baseNamenull
      MissingResourceException - 如果找不到指定基本名称的资源bundle
      参见:
    • getBundle

      public static final ResourceBundle getBundle(String baseName, ResourceBundle.Control control)
      使用指定的基本名称、默认区域设置和指定的控制获取资源bundle。调用此方法等效于调用
      getBundle(baseName, Locale.getDefault(),
                this.getClass().getClassLoader(), control);
      
      除了getClassLoader()是以ResourceBundle的安全权限运行的。有关使用ResourceBundle.Control的完整资源bundle加载过程的描述,请参见getBundle
      参数:
      baseName - 资源包的基本名称,完全限定的类名
      control - 提供资源包加载过程信息的控制器
      返回:
      给定基本名称和默认区域设置的资源包
      抛出:
      NullPointerException - 如果baseNamecontrolnull
      MissingResourceException - 如果找不到指定基本名称的资源包
      IllegalArgumentException - 如果给定的control无法正常执行(例如,control.getCandidateLocales返回null)。注意会根据需要对control进行验证。
      UnsupportedOperationException - 如果在命名模块中调用此方法
      自版本:
      1.6
    • getBundle

      public static final ResourceBundle getBundle(String baseName, Locale locale)
      使用指定的基本名称和区域设置以及调用模块获取资源包。调用此方法等效于调用
          getBundle(baseName, locale, callerModule);
      
      参数:
      baseName - 资源包的基本名称,完全限定的类名
      locale - 欲获取资源包的区域设置
      返回:
      给定基本名称和区域设置的资源包
      抛出:
      NullPointerException - 如果baseNamelocalenull
      MissingResourceException - 如果找不到指定基本名称的资源包
      参见:
    • getBundle

      public static ResourceBundle getBundle(String baseName, Module module)
      代表指定模块使用指定的基本名称和默认区域设置获取资源包。此方法等效于调用
          getBundle(baseName, Locale.getDefault(), module);
      
      参数:
      baseName - 资源包的基本名称,完全限定的类名
      module - 搜索资源包的模块
      返回:
      给定基本名称和默认区域设置的资源包
      抛出:
      NullPointerException - 如果baseNamemodulenull
      SecurityException - 如果存在安全管理器且调用者不是指定模块且没有RuntimePermission("getClassLoader")
      MissingResourceException - 如果在指定模块中找不到指定基本名称的资源包
      自版本:
      9
      参见:
    • getBundle

      public static ResourceBundle getBundle(String baseName, Locale targetLocale, Module module)
      代表指定模块使用指定的基本名称和区域设置获取资源包。

      命名模块中的资源包可能被封装。当从service provider加载资源包时,调用模块必须在其module descriptor中声明模块使用ResourceBundleProvider来获取命名资源包。否则,它将加载给定模块中的本地资源包,就像调用Module.getResourceAsStream(String)或者对给定模块的类加载器可见的资源包,就像调用ClassLoader.getResourceAsStream(String)一样。当从指定模块加载资源包时,将受到Module.getResourceAsStream指定的封装规则的约束。

      如果给定的module是一个未命名模块,则此方法等效于调用getBundle(baseName, targetLocale, module.getClassLoader()以加载对给定未命名模块的类加载器可见的资源包。如果存在自定义ResourceBundleControlProvider实现,则仅在指定模块是未命名模块时才会被调用。

      参数:
      baseName - 资源包的基本名称,完全限定的类名
      targetLocale - 欲获取资源包的区域设置
      module - 搜索资源包的模块
      返回:
      模块中给定基本名称和区域设置的资源包
      抛出:
      NullPointerException - 如果baseNametargetLocalemodulenull
      SecurityException - 如果存在安全管理器且调用者不是指定模块且没有RuntimePermission("getClassLoader")
      MissingResourceException - 如果在指定module中找不到指定基本名称和区域设置的资源包
      自版本:
      9
      参见:
    • getBundle

      public static final ResourceBundle getBundle(String baseName, Locale targetLocale, ResourceBundle.Control control)
      使用指定的基本名称、目标区域设置和控制器以及调用者的类加载器获取资源包。调用此方法等效于调用
      getBundle(baseName, targetLocale, this.getClass().getClassLoader(),
                control);
      
      除了getClassLoader()是以ResourceBundle的安全权限运行的。有关使用ResourceBundle.Control进行资源包加载过程的完整描述,请参阅getBundle
      参数:
      baseName - 资源包的基本名称,完全限定的类名
      targetLocale - 欲获取资源包的区域设置
      control - 提供资源包加载过程信息的控制器
      返回:
      给定基本名称和locales中的Locale的资源包
      抛出:
      NullPointerException - 如果baseNamelocalescontrolnull
      MissingResourceException - 如果在任何locales中找不到指定基本名称的资源包
      IllegalArgumentException - 如果给定的control无法正常执行(例如,control.getCandidateLocales返回null)。注意会根据需要对control进行验证。
      UnsupportedOperationException - 如果在命名模块中调用此方法
      自版本:
      1.6
    • getBundle

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

      当从命名模块调用此方法并且给定的加载器是调用者模块的类加载器时,这等效于调用:

          getBundle(baseName, targetLocale, callerModule);
      
      否则,这等效于调用:
          getBundle(baseName, targetLocale, loader, control);
      
      其中controlResourceBundle.Control的默认实例,除非由ResourceBundleControlProvider SPI提供Control实例。请参阅修改默认行为的描述。以下描述了默认行为。

      资源包搜索和加载策略

      getBundle使用基本名称、指定的区域设置和默认区域设置(从Locale.getDefault获取)生成一系列候选资源包名称。如果指定的区域设置的语言、脚本、国家和变体都是空字符串,则基本名称是唯一的候选资源包名称。否则,从指定区域设置的属性值(语言、脚本、国家和变体)生成候选区域设置列表,并将其附加到基本名称。通常,这看起来像以下内容:

           baseName + "_" + language + "_" + script + "_" + country + "_" + variant
           baseName + "_" + language + "_" + script + "_" + country
           baseName + "_" + language + "_" + script
           baseName + "_" + language + "_" + country + "_" + variant
           baseName + "_" + language + "_" + country
           baseName + "_" + language
       

      候选资源包名称中最后一个组件为空字符串的将被省略,以及下划线。例如,如果国家是空字符串,则上述第二个和第五个候选资源包名称将被省略。同样,如果脚本是空字符串,则包含脚本的候选名称也将被省略。例如,具有语言“de”和变体“JAVA”的区域设置将生成以下基本名称为“MyResource”的候选资源包名称。

           MyResource_de__JAVA
           MyResource_de
       
      在变体包含一个或多个下划线('_')的情况下,通过截断最后一个下划线及其后面部分生成的一系列包名称将插入原始变体的候选资源包名称之后。例如,对于具有语言“en”、脚本“Latn”、国家“US”和变体“WINDOWS_VISTA”的区域设置,以及基本名称“MyResource”,将生成以下候选资源包名称列表:
       MyResource_en_Latn_US_WINDOWS_VISTA
       MyResource_en_Latn_US_WINDOWS
       MyResource_en_Latn_US
       MyResource_en_Latn
       MyResource_en_US_WINDOWS_VISTA
       MyResource_en_US_WINDOWS
       MyResource_en_US
       MyResource_en
       
      注意:对于某些Locale,候选资源包名称列表包含额外的名称,或者资源包名称的顺序略有修改。有关详细信息,请参阅getCandidateLocales的默认实现描述。

      getBundle然后遍历候选资源包名称,以找到第一个可以实例化实际资源包的名称。它使用默认控件的getFormats方法,为每个生成的名称生成两个资源包名称,第一个是类名,第二个是属性文件名。对于每个候选资源包名称,它尝试创建一个资源包:

      • 首先,它尝试使用生成的类名加载一个类。如果可以找到这样的类并使用指定的类加载器加载它,与ResourceBundle兼容的赋值,从ResourceBundle访问,并且可以实例化,则getBundle创建此类的新实例并将其用作结果资源包
      • 否则,getBundle尝试使用生成的属性文件名定位属性资源文件。它通过将候选资源包名称中的所有“.”字符替换为“/”,并附加字符串“.properties”来生成路径名。它尝试使用ClassLoader.getResource找到具有此名称的“资源”。(请注意,“资源”在getResource的意义上与资源包的内容无关,它只是数据的容器,例如文件。)如果找到“资源”,它尝试从其内容创建一个新的PropertyResourceBundle实例。如果成功,此实例将成为结果资源包

      这将继续,直到实例化结果资源包或候选资源包名称列表耗尽。如果找不到匹配的资源包,则调用默认控件的getFallbackLocale方法,该方法返回当前默认区域设置。使用此区域设置生成新的候选区域设置名称序列,并再次搜索,如上所述。

      如果仍然找不到结果资源包,则仅查找基本名称。如果这仍然失败,则抛出MissingResourceException

      找到结果资源包后,将实例化其父级链如果结果资源包已经有一个父级(可能是因为它从缓存返回),则链是完整的。

      否则,getBundle检查在生成结果资源包的过程中使用的候选区域设置列表的其余部分(如前所述,候选资源包名称中最后一个组件为空字符串的将被省略)。当它到达候选列表的末尾时,它尝试普通的资源包名称。对于每个候选资源包名称,它尝试实例化一个资源包(首先查找类,然后查找属性文件,如上所述)。

      每当成功时,它使用新资源包调用先前实例化的资源包的setParent方法。这将继续,直到名称列表耗尽或当前资源包已经具有非空父级。

      完成父级链后,将返回资源包。

      注意:getBundle缓存实例化的资源包,可能多次返回相同的资源包实例。

      注意: baseName参数应为完全限定的类名。但是,为了与早期版本兼容,Java SE运行时环境不会验证这一点,因此可以通过指定路径名(使用“/”)而不是完全限定的类名(使用“.”)来访问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将实例化资源包如下:

      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隐藏。

      API 注意:
      如果调用者模块是命名模块,并且给定的loader是调用者模块的类加载器,则此方法等效于getBundle(baseName, locale);否则,它可能无法从命名模块中找到资源包。请使用getBundle(String, Locale, Module)代替来代表特定模块加载资源包。
      参数:
      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方法,使用目标区域设置获取候选Locales列表,用于搜索资源包。
      4. 调用control.newBundle方法,为基本包名称、候选区域设置和格式实例化一个ResourceBundle。(请参阅下面关于缓存查找的注释。)此步骤在所有候选区域设置和格式的组合上进行迭代,直到newBundle方法返回一个ResourceBundle实例或迭代使用完所有组合为止。例如,如果候选区域设置为Locale("de", "DE")Locale("de")Locale(""),格式为"java.class""java.properties",则以下是要用于调用control.newBundle的区域设置-格式组合序列。
        newBundle的区域设置-格式组合
        索引 Locale format
        1 Locale("de", "DE") java.class
        2 Locale("de", "DE") java.properties
        3 Locale("de") java.class
        4 Locale("de") java.properties
        5 Locale("") java.class
        6 Locale("") java.properties
      5. 如果前一步未找到资源包,则继续到第6步。如果找到一个是基本包(Locale("")的包),且候选区域设置列表只包含Locale(""),则将包返回给调用者。如果找到一个是基本包,但候选区域设置包含除Locale("")之外的区域设置,则将包放置在保留状态,并继续到第6步。如果找到的包不是基本包,则继续到第7步。
      6. 调用control.getFallbackLocale方法,获取一个回退区域设置(当前目标区域设置的替代方案),以进一步尝试查找资源包。如果该方法返回一个非空区域设置,则它成为下一个目标区域设置,并且从第3步重新开始加载过程。否则,如果在前面的第5步中找到了一个基本包并放置在保留状态,则现在将其返回给调用者。否则,将抛出MissingResourceException异常。
      7. 此时,我们已经找到一个不是基本包的资源包。如果此包在实例化期间设置了其父级,则将其返回给调用者。否则,将基于找到的候选区域设置列表实例化其父级链。最后,将该包返回给调用者。

      在上述资源包加载过程中,此工厂方法在调用control.newBundle方法之前查找缓存。如果在缓存中找到的资源包的存活时间已过期,则工厂方法调用control.needsReload方法来确定是否需要重新加载资源包。如果需要重新加载,则工厂方法调用control.newBundle来重新加载资源包。如果control.newBundle返回null,则工厂方法将在缓存中放置一个虚拟资源包,作为不存在资源包的标记,以避免后续请求的查找开销。这些虚拟资源包受control指定的相同过期控制。

      默认情况下,所有加载的资源包都会被缓存。有关详细信息,请参阅control.getTimeToLive

      以下是使用默认ResourceBundle.Control实现的包加载过程示例。

      条件:

      • 基本包名称:foo.bar.Messages
      • 请求的LocaleLocale.ITALY
      • 默认LocaleLocale.FRENCH
      • 可用的资源包:foo/bar/Messages_fr.propertiesfoo/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调用control.getFallbackLocale("foo.bar.Messages", Locale.ITALY),返回Locale.FRENCH。接下来,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.propertiesgetBundle创建一个ResourceBundle实例,成为foo/bar/Messages_fr.properties实例的父级。

      参数:
      baseName - 资源包的基本名称,完全限定的类名
      targetLocale - 欲获取资源包的区域设置
      loader - 用于加载资源包的类加载器
      control - 提供资源包加载过程信息的控制器
      返回:
      给定基本名称和区域设置的资源包
      抛出:
      NullPointerException - 如果baseNametargetLocaleloadercontrolnull
      MissingResourceException - 如果找不到指定基本名称的资源包
      IllegalArgumentException - 如果给定的control无法正常执行(例如,control.getCandidateLocales返回null)。请注意,根据需要执行control的验证。
      UnsupportedOperationException - 如果在命名模块中调用此方法
      自:
      1.6
    • clearCache

      public static final void clearCache()
      从调用者模块加载的所有资源包从缓存中移除。
      自:
      1.6
      参见:
    • clearCache

      public static final void clearCache(ClassLoader loader)
      从给定类加载器加载的所有资源包从缓存中移除。
      参数:
      loader - 类加载器
      抛出:
      NullPointerException - 如果loader为null
      自:
      1.6
      参见:
    • 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
      返回:
      包含在此ResourceBundle及其父包中的所有键的Set
      自版本:
      1.6
    • handleKeySet

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

      默认实现返回由getKeys方法返回的键的Set,除了handleGetObject方法返回null的键。一旦创建了Set,该值将保留在此ResourceBundle中,以避免在后续调用中生成相同的Set。子类可以重写此方法以实现更快的处理。

      返回:
      仅包含在此ResourceBundle中的键的Set
      自版本:
      1.6