模块 java.base
 java.util

类 ResourceBundle

java.lang.Object
java.util.ResourceBundle
已知子类:
ListResourceBundle , PropertyResourceBundle

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

这使您可以编写能够:

  • 易于本地化或翻译成不同的语言
  • 一次处理多个locale
  • 以后可以轻松修改以支持更多locale

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

系列中的每个资源包都包含相同的项,但这些项已针对该资源包所代表的locale进行了翻译。例如,“MyResources”和“MyResources_de”都可能有一个 String 用于取消操作的按钮。在“MyResources”中,String 可能包含“Cancel”,而在“MyResources_de”中,它可能包含“Abbrechen”。

如果不同国家/地区有不同的资源,您可以进行专业化:例如,“MyResources_de_CH”包含瑞士 (CH) 中德语 (de) 的对象。如果您只想修改专业化中的某些资源,您可以这样做。

当您的程序需要特定于locale的对象时,它会使用 getBundle 方法加载 ResourceBundle 类:

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

资源包包含键/值对。这些键唯一地标识包中特定于locale的对象。下面是一个包含两个键/值对的 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”。在上面的示例中,值也是 Strings——“确定”和“取消”——但它们不是必须的。这些值可以是任何类型的对象。

您使用适当的 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 中的方法是线程安全的。

资源包和命名模块

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

资源包与应用程序

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

作为服务提供者的资源包

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

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

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

命名模块中的资源包可能是 encapsulated,因此它不能被其他模块中的代码定位。未命名模块和类路径中的资源包是开放的,任何模块都可以访问。资源包遵循 Module.getResourceAsStream(String) 中指定的资源封装规则。

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

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

如果 getBundle 工厂方法是从堆栈上没有调用者框架的上下文调用的(例如,当直接从 JNI 附加线程调用时),调用者模块默认为 系统类加载器 的未命名模块。

自动模块中的资源包

资源包的常见格式是 。特性 文件格式。通常 .properties 资源包打包在一个 JAR 文件中。只有资源包的 JAR 文件可以很容易地部署为 自动模块。例如,如果 JAR 文件包含条目“p/q/Foo_ja.properties”而没有 .class 条目,则在解析并定义为自动模块时,不会为该模块派生任何包。这允许 .properties 格式的资源包打包在一个或多个 JAR 文件中,这些文件可能包含同一目录中的条目,并且可以作为自动模块成功解析。

ResourceBundle.Control

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

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

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

缓存管理

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 系列。例如,您可以有一组用于异常消息的包,ExceptionResourcesExceptionResources_frExceptionResources_de,...)和一个用于小部件的包,WidgetResourceWidgetResources_frWidgetResources_de,...);随心所欲地分解资源。
自从:
1.1
参见:
  • 字段详细信息

    • parent

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

    • ResourceBundle

      public ResourceBundle()
      唯一的构造方法。 (对于子类构造方法的调用,通常是隐式的。)
  • 方法详情

    • getBaseBundleName

      public String  getBaseBundleName()
      如果已知,则返回此包的基本名称,如果未知,则返回 null。如果不为 null,则这是加载资源包时传递给 ResourceBundle.getBundle(...) 方法的 baseName 参数的值。
      返回:
      资源包的基本名称,由 ResourceBundle.getBundle(...) 方法提供和预期。
      自从:
      1.8
      参见:
    • 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()
      返回此资源包的locale。在调用 getBundle() 之后可以使用此方法来确定返回的资源包是否真正对应于请求的locale或者是后备。
      返回:
      此资源包的locale
    • setParent

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

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

      public static final ResourceBundle  getBundle(String  baseName, ResourceBundle.Control  control)
      使用指定的基本名称、默认locale和指定的控件返回资源包。调用此方法等同于调用
       getBundle(baseName, Locale.getDefault(),
            this.getClass().getClassLoader(), control),
       
      ,只是 getClassLoader() 是以 ResourceBundle 的安全权限运行的。有关使用 ResourceBundle.Control 加载资源包过程的完整描述,请参阅 getBundle
      参数:
      baseName - 资源包的基本名称,一个完全限定的类名
      control - 为资源包加载过程提供信息的控件
      返回:
      给定基本名称和默认locale的资源包
      抛出:
      NullPointerException - 如果 baseNamecontrolnull
      MissingResourceException - 如果找不到指定基本名称的资源包
      IllegalArgumentException - 如果给定的 control 未正确执行(例如,control.getCandidateLocales 返回 null。)请注意,control 的验证是根据需要执行的。
      UnsupportedOperationException - 如果在命名模块中调用此方法
      自从:
      1.6
    • getBundle

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

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

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

      命名模块中的资源包可以被封装。从 服务提供者 加载资源包时,调用者模块必须具有适当的使用条款中的模块描述符声明模块使用 ResourceBundleProvider 作为命名资源包。否则,它将像调用 Module.getResourceAsStream(String) 一样加载给定模块中的本地资源包,或者像调用 ClassLoader.getResourceAsStream(String) 一样加载给定模块的类加载器可见的资源包。当从指定模块加载资源包时,它受制于 Module.getResourceAsStream 指定的封装规则。

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

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

      public static final ResourceBundle  getBundle(String  baseName, Locale  targetLocale, ResourceBundle.Control  control)
      使用指定的基本名称、目标locale和控件以及调用者的类加载器返回资源包。调用此方法等同于调用
       getBundle(baseName, targetLocale, this.getClass().getClassLoader(),
            control),
       
      ,只是 getClassLoader() 是以 ResourceBundle 的安全权限运行的。有关使用 ResourceBundle.Control 加载资源包过程的完整描述,请参阅 getBundle
      参数:
      baseName - 资源包的基本名称,一个完全限定的类名
      targetLocale - 需要资源包的locale
      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)
      使用指定的基本名称、locale和类加载器获取资源包。

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

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

      资源包搜索和加载策略

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

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

      省略最后一个组件为空字符串的候选包名称以及下划线。例如,如果 country 是空字符串,则上面的第二个和第五个候选包名称将被省略。此外,如果 script 是空字符串,则省略包括 script 的候选名称。例如,具有语言“de”和变体“JAVA”的locale将生成下掩码有基本名称“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 然后遍历候选包名称以找到它可以instantiate 实际资源包的第一个。它使用默认控件的 getFormats 方法,为每个生成的名称生成两个包名称,第一个是类名,第二个是属性文件名。对于每个候选包名称,它会尝试创建一个资源包:

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

      这一直持续到结果资源包被实例化或候选包名称列表用完为止。如果未找到匹配的资源包,则调用默认控件的 getFallbackLocale 方法,返回当前的默认locale。如上所述,使用此locale生成新的候选locale名称序列并再次搜索。

      如果仍未找到结果包,则仅查找基本名称。如果仍然失败,则会抛出 MissingResourceException

      一旦找到结果资源包,它的 母链 就会被实例化。如果结果包已经有父级(可能是因为它是从缓存中返回的),那么链就完成了。

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

      只要成功,它就会使用新资源包调用先前实例化的资源包的 setParent 方法。这一直持续到名称列表用完或者当前包已经有一个非空的父包。

      父链完成后,将返回捆绑包。

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

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

      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是 Locale("en", "GB")

      使用以下locale参数调用 getBundle 将实例化资源包,如下所示:

      getBundle() locale到资源包映射
      Locale 资源包
      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”,“美国”) 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 - 需要资源包的locale
      loader - 从中加载资源包的类加载器
      返回:
      给定基本名称和locale的资源包
      抛出:
      NullPointerException - 如果 baseNamelocaleloadernull
      MissingResourceException - 如果找不到指定基本名称的资源包
      自从:
      1.2
      参见:
    • getBundle

      public static ResourceBundle  getBundle(String  baseName, Locale  targetLocale, ClassLoader  loader, ResourceBundle.Control  control)
      使用指定的基本名称、目标locale、类加载器和控件返回资源包。与没有 control 参数的 getBundle 工厂方法不同,给定的 control 指定如何定位和实例化资源包。从概念上讲,给定 control 的包加载过程在以下步骤中执行。
      1. 此工厂方法在缓存中查找指定 baseNametargetLocaleloader 的资源包。如果在缓存中找到请求的资源包实例,并且该实例及其所有父实例的生存时间都没有过期,则将该实例返回给调用者。否则,该工厂方法将继续执行下面的加载过程。
      2. control.getFormats 方法被调用以获取资源包格式以生成包或资源名称。字符串 "java.class""java.properties" 分别指定基于类和 财产 的资源包。以 "java." 开头的其他字符串保留用于将来的扩展,不得用于应用程序定义的格式。其他字符串指定应用程序定义的格式。
      3. 使用目标区域设置调用 control.getCandidateLocales 方法以获取搜索资源包的 candidate Locale s 列表。
      4. control.newBundle 方法被调用以实例化一个 ResourceBundle 用于基本包名称、候选locale和格式。 (请参阅下面有关缓存查找的注释。)此步骤将遍历候选locale和格式的所有组合,直到 newBundle 方法返回一个 ResourceBundle 实例或迭代用完所有组合。例如,如果候选区域设置为 Locale("de", "DE")Locale("de")Locale(""),格式为 "java.class""java.properties",则以下是用于调用 control.newBundle 的区域设置-格式组合序列。
        newBundle 的locale格式组合
        索引 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(""),则将包返回给调用者。如果发现一个包是基本包,但候选locale列表包含 Locale("") 以外的locale,则搁置该包并继续执行步骤 6。如果发现一个包不是基本包,继续执行步骤 7。
      6. control.getFallbackLocale 方法被调用以获取后备locale(替代当前目标locale)以尝试进一步查找资源包。如果该方法返回一个非空locale,它将成为下一个目标locale,并且加载过程从第 3 步重新开始。否则,如果在前面的第 5 步中找到并搁置了一个基本包,则将其返回给调用者现在。否则,将抛出 MissingResourceException。
      7. 此时,我们找到了一个不是基础包的资源包。如果此包在其实例化期间设置了其父项,则将其返回给调用者。否则,它的 母链 是根据从中找到它的候选locale列表实例化的。最后,包返回给调用者。

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

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

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

      状况:

      • 基本包名称:foo.bar.Messages
      • 请求 Locale : Locale.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 从候选locale列表中设置其父链。在列表中仅找到 foo/bar/Messages.propertiesgetBundle 创建了一个 ResourceBundle 实例,该实例成为 foo/bar/Messages_fr.properties 实例的父实例。

      参数:
      baseName - 资源包的基本名称,一个完全限定的类名
      targetLocale - 需要资源包的locale
      loader - 从中加载资源包的类加载器
      control - 为资源包加载过程提供信息的控件
      返回:
      给定基本名称和locale的资源包
      抛出:
      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 为空
      自从:
      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()
      返回此 ResourceBundle 及其父包中包含的所有键的 Set
      返回:
      ResourceBundle 及其父包中包含的所有密钥的 Set
      自从:
      1.6
    • handleKeySet

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

      默认实现返回 getKeys 方法返回的键的 Set,但 handleGetObject 方法返回 null 的键除外。创建 Set 后,该值将保留在此 ResourceBundle 中,以避免在后续调用中产生相同的 Set。子类可以覆盖此方法以加快处理速度。

      返回:
      一个 Set 的键只包含在这个 ResourceBundle
      自从:
      1.6