Module  java.base
软件包  java.util

Class ResourceBundle

  • 已知直接子类:
    ListResourceBundlePropertyResourceBundle


    public abstract class ResourceBundle
    extends Object
    资源束包含区域特定的对象。 当您的程序需要特定于区域设置的资源(例如, String ,您的程序可以从适合当前用户的区域设置的资源包中加载它。 以这种方式,您可以编写程序代码,这个程序代码大部分独立于用户的区域设置,以隔离资源束中大部分(如果不是全部)特定于区域设置的信息。

    这样就可以编写程序:

    • 容易本地化或翻译成不同的语言
    • 一次处理多个区域设置
    • 稍后可以轻松修改以支持更多的区域设置

    资源束属于其成员共享公共基本名称但其名称还具有标识其区域设置的其他组件的家族。 例如,资源束系列的基本名称可能是“MyResources”。 家庭应该有一个默认的资源包,它与其家族名称 - “MyResources”完全相同,如果不支持特定的区域设置,将会被用作最后的包。 然后,家族可以根据需要提供尽可能多的特定于区域的成员,例如名为“MyResources_de”的德语。

    一个系列中的每个资源包都包含相同的项目,但这些项目已被翻译成由该资源包所表示的区域设置。 例如,“MyResources”和“MyResources_de”都可能有一个用于取消操作的按钮上使用的String 在“MyResources”中, String可能包含“取消”,在“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 s。 在这个例子中,键是“OkKey”和“CancelKey”。 在上面的例子中,值也是String s - “OK”和“Cancel” - 但是它们不一定是。 值可以是任何类型的对象。

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

     button1 = new Button(myResources.getString("OkKey"));
     button2 = new Button(myResources.getString("CancelKey"));
     
    getter方法都需要键作为参数,并返回对象(如果找到)。 如果没有找到对象,那么getter方法会抛出一个MissingResourceException

    除了getString之外, ResourceBundle还提供了一种获取字符串数组的方法, getStringArray以及用于任何其他类型对象的通用的getObject方法。 使用getObject ,您必须将结果转换为适当的类型。 例如:

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

    Java平台提供的两个子类ResourceBundleListResourceBundlePropertyResourceBundle ,提供一个相当简单的方法来创建资源。 如前面的例子中所示, ListResourceBundle其资源作为键/值对列表进行管理。 PropertyResourceBundle使用属性文件来管理其资源。

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

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

    Resource Bundles in Named Modules

    当资源束部署在命名模块中时,将应用以下模块特定的要求和限制。
    • 调用getBundle(String, Locale)的命名模块中的代码将在调用者模块( 调用者模块 )中定位资源束。
    • 如果将资源束部署在与调用者模块分开的命名模块中,则需要从ResourceBundleProvider服务提供商加载这些资源束。 调用者模块必须声明“ uses ”,服务接口名称是基本名称的包名称字符串“ .spi. ”,基本名称的简单类名称和字符串“ Provider ”的连接。 包含资源束的包提供者模块必须使用服务接口名称及其实现类名称声明“ provides ”。 例如,如果基本名称是“ com.example.app.MyResources ”时,呼叫者模块必须声明“ uses com.example.app.spi.MyResourcesProvider; ”和包含资源包的模块必须声明“ provides com.example.app.spi.MyResourcesProvider with com.example.app.internal.MyResourcesProviderImpl; ”,其中com.example.app.internal.MyResourcesProviderImpl是一个实现类的com.example.app.spi.MyResourcesProvider
    • 如果要在命名模块(如XML)中使用非标准格式, 需要使用ResourceBundleProvider
    • getBundle方法与ClassLoader可能无法找到使用给定的资源包ClassLoader命名模块。 可以使用具有ModulegetBundle方法。
    • 命名模块支持ResourceBundle.Control 如果在命名模块中调用ResourceBundle.ControlgetBundle方法,则该方法将抛出一个UnsupportedOperationException 任何ResourceBundleControlProvider服务提供商都将在命名模块中被忽略。

    ResourceBundleProvider Service Providers

    getBundle工厂方法加载服务提供商ResourceBundleProvider ,如果可用,使用ServiceLoader 服务类型由<package name> + ".spi." + <simple name> + "Provider"指定。 例如,如果基本名称为“ com.example.app.MyResources ”,则服务类型为com.example.app.spi.MyResourcesProvider

    在命名模块中,给定基本名称的加载服务提供程序用于加载资源束。 如果没有服务提供商可用,或者如果没有一个服务提供者返回一个资源包,并且调用者模块没有自己的服务提供商,则getBundle工厂方法将搜索调用者模块中本地的可见资源束到调用者模块的类加载器。 本地模块搜索的资源束格式为“java.class”和“java.properties”。

    的ResourceBundle.Control

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

    For the getBundle factory方法不需要ResourceBundle.Control实例,其default behavior的资源束加载可以通过自定义修改ResourceBundleControlProvider实现。 如果任何一个提供商为给定的基础名称提供了一个ResourceBundle.Control那么将使用ResourceBundle.Control而不是默认的ResourceBundle.Control 如果有多个服务提供商支持相同的基本名称,则将使用从ServiceLoader返回的第一个。 命名模块将忽略自定义ResourceBundle.Control实现。

    缓存管理

    默认情况下, getBundle工厂方法创建的资源束实例被缓存,如果已经缓存,工厂方法返回相同的资源束实例多次。 getBundle客户端可以清除缓存,使用生存时间值管理缓存的资源包实例的生命周期,或指定不缓存资源束实例。 请参阅的描述getBundlefactory methodclearCacheResourceBundle.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的家庭。 例如,你可以有异常的消息一组捆, ExceptionResourcesExceptionResources_frExceptionResources_de ,...),以及一个用于小部件, WidgetResourceWidgetResources_frWidgetResources_de ,...); 分解你喜欢的资源。
    从以下版本开始:
    1.1
    另请参见:
    ListResourceBundlePropertyResourceBundleMissingResourceExceptionResourceBundleProvider
    • 字段详细信息

      • parent

        protected ResourceBundle parent
        此捆绑包的父捆绑。 当该包不包含特定资源时,将通过getObject搜索父包。
    • 构造方法详细信息

      • ResourceBundle

        public ResourceBundle​()
        唯一的构造函数。 (用于子类构造函数的调用,通常是隐式的。)
    • 方法详细信息

      • getBaseBundleName

        public String getBaseBundleName​()
        如果已知,则返回此包的基本名称,如果未知,则返回null 如果不为空,那么这是在加载资源束时传递给ResourceBundle.getBundle(...)方法的baseName参数的值。
        结果
        资源束的基本名称,由 ResourceBundle.getBundle(...)方法提供和预期。
        从以下版本开始:
        1.8
        另请参见:
        getBundle(java.lang.String, java.util.Locale, java.lang.ClassLoader)
      • 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从此资源束获取对象。 如果不成功,并且父资源束不为空,则调用父级的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()),
        除了getClassLoader()运行的安全权限为ResourceBundle 有关搜索和实例化策略的完整描述,请参阅getBundle
        参数
        baseName - 资源包的基本名称,一个完全限定的类名
        结果
        给定基本名称和默认语言环境的资源包
        异常
        NullPointerException - 如果 baseNamenull
        MissingResourceException - 如果没有找到指定基本名称的资源束
      • getBundle

        public static final ResourceBundle getBundle​(String baseName,
                                                     ResourceBundle.Control control)
        X- 2004545 CEEC X- 调用此方法相当于调用
          getBundle(baseName, Locale.getDefault(),
                   this.getClass().getClassLoader(), control), 
        除了getClassLoader()运行的安全权限为ResourceBundle 有关ResourceBundle.Control的资源包加载过程的完整说明,请参阅ResourceBundle.Control
        参数
        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, this.getClass().getClassLoader()),
        除了getClassLoader()的安全权限为ResourceBundle 有关搜索和实例化策略的完整描述,请参阅getBundle
        参数
        baseName - 资源包的基本名称,一个完全限定的类名
        locale - 需要资源束的区域设置
        结果
        给定的基本名称和语言环境的资源包
        异常
        NullPointerException - 如果 baseNamelocalenull
        MissingResourceException - 如果没有找到指定基本名称的资源束
      • getBundle

        public static ResourceBundle getBundle​(String baseName,
                                               Module module)
        使用指定的基本名称和默认语言环境代替指定的模块获取资源包。 这个方法相当于调用
        getBundle(baseName, Locale.getDefault(), module)

        命名模块中的资源束可能被封装。 当资源包从提供程序加载时,调用者模块必须在其模块描述符中具有适当的uses子句,以声明该模块使用<package name> + ".spi." + <simple name> + "Provider"实现。 否则,它将加载给定模块中本地的资源束,或对给定模块的类加载器可见的资源束(有关详细信息,请参阅Resource Bundles in Named Modules部分)。 当从指定的模块加载资源束时,会受到Module.getResourceAsStream指定的封装规则的约束

        参数
        baseName - 资源包的基本名称,一个完全限定的类名
        module - 搜索资源束的模块
        结果
        给定基本名称和默认语言环境的资源包
        异常
        NullPointerException - 如果 baseNamemodulenull
        SecurityException - 如果安全管理器存在,并且调用方不是指定的模块,并且没有 RuntimePermission("getClassLoader")
        MissingResourceException - 如果在指定的模块中找不到指定基本名称的资源束
        从以下版本开始:
        9
        另请参见:
        ResourceBundleProvider
      • getBundle

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

        命名模块中的资源束可能被封装。 当资源束从提供程序加载时,调用者模块必须在其模块描述符中具有适当的uses子句,以声明该模块使用<package name> + ".spi." + <simple name> + "Provider"实现。 否则,它将加载给定模块中本地的资源束,或者给定模块的类加载器可见的资源束(有关详细信息,请参阅Resource Bundles in Named Modules部分)。 当资源束从指定的模块加载时,它受到Module.getResourceAsStream指定的封装规则的约束

        如果给定的module是一个未命名的模块,那么此方法相当于调用getBundle(baseName, targetLocale, module.getClassLoader()来加载给定未命名模块的类加载器可见的资源束。 如果存在,自定义的ResourceBundleControlProvider实现将仅在指定的模块是未命名的模块时被调用。

        参数
        baseName - 资源包的基本名称,一个完全限定的类名
        targetLocale - 需要资源束的区域设置
        module - 搜索资源束的模块
        结果
        模块中给定基本名称和区域设置的资源束
        异常
        NullPointerException -如果 baseNametargetLocale ,或 modulenull
        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的资源包加载过程的完整说明,请参阅ResourceBundle.Control
        参数
        baseName - 资源包的基本名称,一个完全限定的类名
        targetLocale - 需要资源束的区域设置
        control - 为资源束加载过程提供信息的控件
        结果
        一个给定基本名称的资源束,一个 Localelocales
        异常
        NullPointerException -如果 baseNamelocales或者 controlnull
        MissingResourceException - 如果没有找到任何 locales指定的基本名称的资源束。
        IllegalArgumentException - 如果给定的 control无法正常执行(例如, control.getCandidateLocales返回null。)请注意,根据需要执行 control验证。
        UnsupportedOperationException - 如果在命名模块中调用此方法
        从以下版本开始:
        1.6
      • getBundle

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

        该方法的行为与调用getBundle(String, Locale, ClassLoader, Control)传递默认实例ResourceBundle.Control相同,除非另有ResourceBundle.ControlResourceBundleControlProvider SPI一起提供。 请参阅modifying the default behavior的说明。

        The following describes the default behavior

        命名模块中的资源束对该模块是私有的。 如果调用者在命名模块中,则该方法将从服务提供商ResourceBundleProvider找到资源束。 否则,它将加载给定的可见的资源束loader (有关详细信息,请参阅Resource Bundles in Named Modules部分)。 如果调用者在命名模块中,给定的loader与调用者的类加载器不同,或者如果调用者不在命名模块中,则此方法将不会从命名模块中找到资源束。

        getBundle使用基本名称,指定的区域设置和默认语言环境(从Locale.getDefault获得)生成candidate bundle names的序列。 如果指定的语言环境的语言,脚本,国家和变体都是空字符串,则基本名称是唯一的候选包名称。 否则,从指定的区域设置(语言,脚本,国家和变体)的属性值生成候选语言环境列表,并附加到基本名称。 通常,这将如下所示:

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

        最后一个组件是一个空字符串的候选组名称,以及下划线。 例如,如果country是一个空字符串,那么上面的第二个和第五个候选组名将被省略。 此外,如果脚本是空字符串,则省略包含脚本的候选名称。 例如,具有语言“de”和变体“JAVA”的区域设置将产生下面具有基本名称“MyResource”的候选名称。

          MyResource_de__JAVA
             MyResource_de 
        在变体包含一个或多个下划线('_')的情况下,通过截断最后一个下划线及其后面的部分生成的捆绑名称序列将插入到具有原始变体的候选包名称之后。 例如,对于具有语言“en”的语言环境,脚本“Latn,country”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 
        Note: For some Locales, the list of candidate bundle names contains extra names, or the order of bundle names is slightly modified. See the description of the default implementation of getCandidateLocales for details.

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

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

        这将一直持续到结果资源束被实例化或者候选包名称列表用尽。 如果没有找到匹配的资源束,则调用默认控件的getFallbackLocale方法,返回当前的默认语言环境。 使用该语言环境生成新的候选语言环境名称序列,并重新搜索,如上所述。

        如果仍然没有找到结果包,则单独查看基本名称。 如果仍然失败,则抛出MissingResourceException

        Once a result resource bundle has been found, its parent chain is instantiated 如果结果包已经有一个父(可能是因为它从一个缓存返回),那么链就完成了。

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

        无论何时成功,它将使用新的资源束调用先前实例化的资源束的setParent方法。 这一直持续到名称列表用尽,或者当前的包已经有一个非空的父项。

        一旦父链完成,则返回捆绑包。

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

        注意: baseName参数应该是一个完全限定的类名。 然而,为了与早期版本兼容,Sun的Java SE运行时环境不会验证这一点,因此可以通过指定路径名(使用“/”)而不是完全限定的类名称(使用“。”来访问PropertyResourceBundle )。 )。

        Example:

        提供以下类和属性文件:

          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 to resource bundle mapping Locale("fr", "CH") MyResources_fr_CH.class, parent MyResources_fr.properties, parent MyResources.class Locale("fr", "FR") MyResources_fr.properties, parent MyResources.class Locale("de", "DE") MyResources_en.properties, parent MyResources.class Locale("en", "US") MyResources_en.properties, parent MyResources.class Locale("es", "ES") MyResources_es_ES.class, parent MyResources.class

        文件MyResources_fr_CH.properties永远不会被使用,因为它被MyResources_fr_CH.class隐藏。 同样,MyResources.properties也被MyResources.class隐藏。

        API Note:
        如果调用者模块是一个命名模块,给定的loader是调用者模块的类加载器,则此方法相当于getBundle(baseName, locale) ; 否则,它将不会从命名模块找到资源束。 使用getBundle(String, Locale, Module)代替在特定模块上加载资源束。
        参数
        baseName - 资源包的基本名称,一个完全限定的类名
        locale - 需要资源束的区域设置
        loader - 从中加载资源束的类加载器
        结果
        给定的基本名称和语言环境的资源包
        异常
        NullPointerException -如果 baseNamelocale ,或 loadernull
        MissingResourceException - 如果没有找到指定的基本名称的资源束
        从以下版本开始:
        1.2
      • getBundle

        public static ResourceBundle getBundle​(String baseName,
                                               Locale targetLocale,
                                               ClassLoader loader,
                                               ResourceBundle.Control control)
        使用指定的基本名称,目标语言环境,类加载器和控件返回资源包。 getBundlefactory methods with no controlargument不同,给定的control指定了如何定位和实例化资源束。 在概念上,具有给定的control的捆绑包加载过程在以下步骤中执行。
        1. 此工厂方法查找该指定的高速缓存中的资源包baseNametargetLocaleloader 如果在缓存中找到请求的资源束实例,并且实例及其所有父实例的生存周期尚未过期,则将该实例返回给调用者。 否则,此工厂方法继续下面的加载过程。
        2. 调用control.getFormats方法来获取资源束格式来生成包或资源名称。 字符串"java.class""java.properties"指定基于类和基于property的资源束。 "java."开头的其他字符串保留用于将来的扩展名,不能用于应用程序定义的格式。 其他字符串指定应用程序定义格式。
        3. 使用目标区域设置调用control.getCandidateLocales方法以获取搜索资源束的候选Locale列表。
        4. 调用control.newBundle方法来实例化基本包名称,候选区域设置和格式的ResourceBundle (请参阅下面的缓存查找的注释。)这一步遍历候选语言环境和格式的所有组合,直到newBundle方法返回一个ResourceBundle实例或迭代已经耗尽了所有组合。 例如,如果候选区域设置是Locale("de", "DE")Locale("de")Locale("")和格式是"java.class""java.properties" ,再下面是语言环境格式组合的序列,以用于调用control.newBundle locale-format combinations for newBundle Locale
          format
          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.如果发现一个bundle不是基础包,进入步骤7。
        6. 调用control.getFallbackLocale方法来获取后备区域设置(替代当前目标区域设置)以尝试进一步查找资源束。 如果该方法返回非空区域设置,它将成为下一个目标区域设置,加载过程从步骤3开始。否则,如果在前一步骤5中找到并保留基础包,则返回给调用者现在。 否则,将抛出MissingResourceException异常。
        7. 在这一点上,我们发现一个资源束不是基础包。 如果此捆绑包在其实例化期间设置其父级,则将其返回给调用者。 否则,其parent chain将根据找到的候选语言环境列表进行实例化。 最后,该包返回给调用者。

        在上述资源包加载过程中,此工厂方法在调用control.newBundle方法之前查找缓存。 如果高速缓存中发现的资源束的生存周期已过期,则工厂方法将调用control.needsReload方法来确定资源束是否需要重新加载。 如果需要重新加载,工厂方法调用control.newBundle重新加载资源包。 如果control.newBundle返回null ,则工厂方法将虚拟资源束放在缓存中作为不存在的资源束的标记,以避免后续请求的查找开销。 这种虚拟资源束处于与control所指定的相同的到期控制下。

        默认情况下,加载的所有资源束都被缓存。 详情请参阅control.getTimeToLive

        以下是使用默认的ResourceBundle.Control实现的捆绑包加载过程的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.properties ,而getBundle创建一个ResourceBundle实例,成为ResourceBundle实例的父foo/bar/Messages_fr.properties

        参数
        baseName - 资源包的基本名称,一个完全限定的类名
        targetLocale - 需要资源束的区域设置
        loader - 从中加载资源束的类加载器
        control - 为资源束加载过程提供信息的控件
        结果
        给定的基本名称和语言环境的资源包
        异常
        NullPointerException -如果 baseNametargetLocaleloader ,或 controlnull
        MissingResourceException - 如果没有找到指定的基础名称的资源束
        IllegalArgumentException - 如果给定的 control不正确执行(例如, control.getCandidateLocales返回null。)请注意,根据需要执行 control验证。
        UnsupportedOperationException - 如果在命名模块中调用此方法
        从以下版本开始:
        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
        结果
        true如果给定的key包含在这个ResourceBundle或其父包中; false否则。
        异常
        NullPointerException - 如果 keynull
        从以下版本开始:
        1.6
      • keySet

        public Set<String> keySet​()
        返回 Set包含在此的所有键的 ResourceBundle及其父包。
        结果
        一个 Set包含在此的所有键的 ResourceBundle及其父包。
        从以下版本开始:
        1.6
      • handleKeySet

        protected Set<String> handleKeySet​()
        返回一个Set的键包含在这个ResourceBundle

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

        结果
        一个 Set的键只包含在这个 ResourceBundle
        从以下版本开始:
        1.6