模块  java.base
软件包  java.util

Class ResourceBundle.Control

  • Enclosing class:
    ResourceBundle

    public static class ResourceBundle.Control
    extends Object
    ResourceBundle.Control定义了一组回调方法,这些方法在捆绑加载过程中由ResourceBundle.getBundle工厂方法调用。 换句话说, ResourceBundle.Control与工厂方法协作以加载资源包。 回调方法的默认实现提供了工厂方法执行default behavior所需的信息。

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

    除了回调方法之外, toBundleNametoResourceName方法的定义主要是为了方便实现回调方法。 但是,可以重写toBundleName方法,以在组织和本地化资源的打包中提供不同的约定。 toResourceName方法是final以避免使用错误的资源和类名分隔符。

    两种工厂方法getControl(List)getNoFallbackControl(List)提供ResourceBundle.Control实例, ResourceBundle.Control实例实现默认捆绑加载过程的常见变体。

    在返回的格式getFormats通过返回的方法和候选语言环境getCandidateLocales方法必须全部一致ResourceBundle.getBundle调用了同样的基本包。 否则, ResourceBundle.getBundle方法可能会返回非预期的包。 例如,如果getFormats方法仅为第一次呼叫"java.class"返回ResourceBundle.getBundle而第二次呼叫仅"java.properties" ,则第二次呼叫将返回在第一次呼叫期间缓存的基于类的呼叫。

    如果ResourceBundle.Control实例同时由多个线程使用,则它必须是线程安全的。 ResourceBundle.getBundle不同步以调用ResourceBundle.Control方法。 这些方法的默认实现是线程安全的。

    应用程序可以指定ResourceBundle.Control通过返回的情况下getControl工厂方法或从创建的子类ResourceBundle.Control定制包加载进程。 以下是更改默认捆绑加载过程的示例。

    例1

    以下代码允许ResourceBundle.getBundle仅查找基于属性的资源。

      import java.util.*;
     import static java.util.ResourceBundle.Control.*;
     ...
     ResourceBundle bundle =
       ResourceBundle.getBundle("MyResources", new Locale("fr", "CH"),
                                ResourceBundle.Control.getControl(FORMAT_PROPERTIES)); 
    鉴于ResourceBundle.getBundle描述中example中的资源包,此ResourceBundle.getBundle调用加载MyResources_fr_CH.properties ,其父级为MyResources_fr.properties ,其父级为MyResources.properties MyResources_fr_CH.properties未隐藏,但MyResources_fr_CH.class是。)

    例2

    以下是使用Properties.loadFromXML加载基于XML的包的示例

      ResourceBundle rb = ResourceBundle.getBundle("Messages",
         new ResourceBundle.Control() {
             public List<String> getFormats(String baseName) {
                 if (baseName == null)
                     throw new NullPointerException();
                 return Arrays.asList("xml");
             }
             public ResourceBundle newBundle(String baseName,
                                             Locale locale,
                                             String format,
                                             ClassLoader loader,
                                             boolean reload)
                              throws IllegalAccessException,
                                     InstantiationException,
                                     IOException {
                 if (baseName == null || locale == null
                       || format == null || loader == null)
                     throw new NullPointerException();
                 ResourceBundle bundle = null;
                 if (format.equals("xml")) {
                     String bundleName = toBundleName(baseName, locale);
                     String resourceName = toResourceName(bundleName, format);
                     InputStream stream = null;
                     if (reload) {
                         URL url = loader.getResource(resourceName);
                         if (url != null) {
                             URLConnection connection = url.openConnection();
                             if (connection != null) {
                                 // Disable caches to get fresh data for
                                 // reloading.
                                 connection.setUseCaches(false);
                                 stream = connection.getInputStream();
                             }
                         }
                     } else {
                         stream = loader.getResourceAsStream(resourceName);
                     }
                     if (stream != null) {
                         BufferedInputStream bis = new BufferedInputStream(stream);
                         bundle = new XMLResourceBundle(bis);
                         bis.close();
                     }
                 }
                 return bundle;
             }
         });
    
     ...
    
     private static class XMLResourceBundle extends ResourceBundle {
         private Properties props;
         XMLResourceBundle(InputStream stream) throws IOException {
             props = new Properties();
             props.loadFromXML(stream);
         }
         protected Object handleGetObject(String key) {
             return props.getProperty(key);
         }
         public Enumeration<String> getKeys() {
             ...
         }
     } 
    API Note:
    命名模块不支持ResourceBundle.Control 如果在命名模块中调用ResourceBundle.getBundle方法和ResourceBundle.Control ,则该方法将抛出UnsupportedOperationException 在命名模块中将忽略ResourceBundleControlProvider任何服务提供者。
    从以下版本开始:
    1.6
    另请参见:
    ResourceBundleProvider
    • 字段详细信息

      • FORMAT_DEFAULT

        public static final List<String> FORMAT_DEFAULT
        默认格式List ,按此顺序包含字符串"java.class""java.properties" List不可修改。
        另请参见:
        getFormats(String)
      • FORMAT_CLASS

        public static final List<String> FORMAT_CLASS
        仅限类的格式List包含"java.class" List不可修改。
        另请参见:
        getFormats(String)
      • FORMAT_PROPERTIES

        public static final List<String> FORMAT_PROPERTIES
        仅限属性List包含"java.properties" List不可修改。
        另请参见:
        getFormats(String)
      • TTL_NO_EXPIRATION_CONTROL

        public static final long TTL_NO_EXPIRATION_CONTROL
        生存时间常量,用于禁用缓存中已加载资源包实例的到期控制。
        另请参见:
        getTimeToLive(String, Locale)常数字段值
    • 构造方法详细信息

      • Control

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

      • getFormats

        public List<String> getFormats​(String baseName)
        返回ListString s,其中包含用于加载给定baseName资源包的baseName ResourceBundle.getBundle工厂方法尝试按照列表指定的顺序加载格式的资源包。 此方法返回的列表必须至少有一个String 预定义的格式是"java.class"对于基于类的资源包和"java.properties"properties-based分的。 "java."开头的字符串保留用于将来的扩展,不得由应用程序定义的格式使用。

        不要求返回不可变(不可修改) List 但是,返回的ListList返回后getFormats

        默认实现返回FORMAT_DEFAULT以便ResourceBundle.getBundle工厂方法查找基于类的基于资源的包,然后查找基于属性的资源包。

        参数
        baseName - 资源包的基本名称,完全限定的类名
        结果
        ListString其中包含用于加载资源包的格式。
        异常
        NullPointerException - 如果 baseName为空
        另请参见:
        FORMAT_DEFAULTFORMAT_CLASSFORMAT_PROPERTIES
      • getCandidateLocales

        public List<Locale> getCandidateLocales​(String baseName,
                                                Locale locale)
        返回ListLocale s作为baseNamelocale候选语言环境。 每次工厂方法尝试为目标Locale查找资源束时, ResourceBundle.getBundle工厂方法都会调用此方法。

        如果候选语言环境的相应资源包存在且其父项未由加载的资源包本身定义,则候选语言环境的序列也对应于运行时资源查找路径(也称为父链 )。 如果希望将基本包作为父链的终端,则列表的最后一个元素必须是root locale

        如果给定的区域设置为等于Locale.ROOT (根区域),一个List只包含根Locale必须返回。 在这种情况下, ResourceBundle.getBundle工厂方法仅将基础包加载为生成的资源包。

        不要求返回不可变(不可修改) List 但是,返回的ListList返回后getCandidateLocales

        缺省的实现返回一个List含有Locale使用下述的规则秒。 在下面的描述中, LSCV分别表示非空语言,脚本,国家和变体。 例如,[ LC ]表示Locale ,其仅具有语言和国家/地区的非空值。 形式L (“xx”)表示(非空)语言值是“xx”。 对于所有情况, Locale最终组件值为空字符串的Locale

        1. 对于具有空脚本值的输入Locale ,通过逐个省略最终组件来附加候选Locale ,如下所示:
          • [ LCV ]
          • [ LC ]
          • [ L ]
          • Locale.ROOT
        2. 对于具有非空脚本值的输入Locale ,通过省略语言的最终组件来附加候选Locale ,然后附加从Locale生成的Locale国家和变体:
          • [ LSCV ]
          • [ LSC ]
          • [ LS ]
          • [ LCV ]
          • [ LC ]
          • [ L ]
          • Locale.ROOT
        3. 对于具有由下划线分隔的多个子标签组成的变体值的输入Locale ,通过逐个省略变体子标签生成候选Locale ,然后在每次出现Locale之后插入它们,并在原始列表中使用完整变量值。 例如,如果变体由两个子标签V1V2组成
          • [ LSCV1V2 ]
          • [ LSCV1 ]
          • [ LSC ]
          • [ LS ]
          • [ LCV1V2 ]
          • [ LCV1 ]
          • [ LC ]
          • [ L ]
          • Locale.ROOT
        4. 中国特例。 当输入Locale具有语言“zh”(中文)和空脚本值时,可能会提供“Hans”(简体)或“Hant”(繁体),具体取决于国家/地区。 当国家是“CN”(中国)或“SG”(新加坡)时,提供“汉斯”。 当国家为“香港”(中国香港特别行政区),“MO”(澳门特别行政区中国)或“TW”(台湾)时,提供“Hant”。 对于所有其他国家/地区或国家/地区为空时,不提供脚本。 例如,对于Locale("zh", "CN") ,候选列表将是:
          • [ L (“zh”), S (“Hans”), C (“CN”)]
          • [ L (“zh”), S (“Hans”)]
          • [ L (“zh”), C (“CN”)]
          • [ L (“zh”)]
          • Locale.ROOT
          对于Locale("zh", "TW") ,候选人名单将是:
          • [ L (“zh”), S (“Hant”), C (“TW”)]
          • [ L (“zh”), S (“Hant”)]
          • [ L (“zh”), C (“TW”)]
          • [ L (“zh”)]
          • Locale.ROOT
        5. 挪威语的特例。 Locale("no", "NO", "NY")Locale("nn", "NO")代表挪威尼诺斯克。 当语言环境的语言为“nn”时,标准候选列表最多生成[ L (“nn”)],然后添加以下候选项:
          • [ L (“no”), C (“NO”), V (“NY”)]
          • [ L (“否”), C (“否”)]
          • [ L (“否”)]
          • Locale.ROOT
          如果区域设置恰好是Locale("no", "NO", "NY") ,则首先将其转换为Locale("nn", "NO") ,然后执行上述过程。

          此外,Java将语言“no”视为NorwegianBokmÃ¥l“nb”的同义词。 除了单个案例Locale("no", "NO", "NY") (上面已处理),当输入Locale具有语言“no”或“nb”时,具有语言代码“no”和“nb”的候选Locale是交错的,首先使用所请求的语言,然后使用其代名词。 例如, Locale("nb", "NO", "POSIX")生成以下候选列表:

          • [ L (“nb”), C (“NO”), V (“POSIX”)]
          • [ L (“no”), C (“NO”), V (“POSIX”)]
          • [ L (“nb”), C (“否”)]
          • [ L (“否”), C (“否”)]
          • [ L (“nb”)]
          • [ L (“否”)]
          • Locale.ROOT
          Locale("no", "NO", "POSIX")将生成相同的列表,除了带有“no”的语言环境将出现在具有“nb”的相应语言环境之前。

        默认实现使用ArrayList ,覆盖实现可以在将其返回给调用者之前进行修改。 但是,子类在getCandidateLocales返回后不能修改它。

        例如,如果给定的baseName是“消息”而给定的localeLocale("ja", "", "XX") ,那么ListLocale s:

          Locale("ja", "", "XX")
             Locale("ja")
             Locale.ROOT 
        被退回。 如果找到“ja”和“” Locale的资源包,那么运行时资源查找路径(父链)是:
           Messages_ja -> Messages  
        参数
        baseName - 资源包的基本名称,完全限定的类名
        locale - 需要资源包的语言环境
        结果
        ListLocalelocale
        异常
        NullPointerException - 如果 baseNamelocalenull
      • getFallbackLocale

        public Locale getFallbackLocale​(String baseName,
                                        Locale locale)
        返回Locale ,以用作ResourceBundle.getBundle工厂方法进一步搜索资源包的后备区域设置。 每次没有找到baseNamelocale结果资源包时,将从工厂方法调用此方法,其中locale是ResourceBundle.getBundle的参数或此方法返回的先前回退区域设置。

        如果不需要进一步的回退搜索,则该方法返回null

        如果给定的locale不是默认值,则默认实现返回default Locale 否则,返回null

        参数
        baseName - 资源包的基本名称, ResourceBundle.getBundle无法找到任何资源包的完全限定类名(基本包除外)
        locale - Locale ,其中 ResourceBundle.getBundle无法找到任何资源束(基本捆绑包除外)
        结果
        一个 Locale用于回退搜索,或 null如果没有进一步的回退搜索是期望的。
        异常
        NullPointerException - 如果 baseNamelocalenull
      • newBundle

        public ResourceBundle newBundle​(String baseName,
                                        Locale locale,
                                        String format,
                                        ClassLoader loader,
                                        boolean reload)
                                 throws IllegalAccessException,
                                        InstantiationException,
                                        IOException
        如果需要,使用给定的类加载器为给定格式和语言环境的给定包名称实例化资源包。 如果没有可用于给定参数的资源束,则此方法返回null 如果由于意外错误而无法实例化资源包,则必须通过抛出Error异常来报告错误,而不是简单地返回null

        如果reload标志为true ,则表示正在调用此方法,因为先前加载的资源包已过期。

        实现要求:
        命名模块中的资源包受Module.getResourceAsStream指定的封装规则的约束 当无条件打开与资源包对应的资源文件的包时,可以访问给定类加载器可见的命名模块中的资源包。

        默认实现如下所示实例化ResourceBundle

        参数
        baseName - 资源包的基本包名称,完全限定的类名
        locale - 应为其实例化资源包的语言环境
        format - 要加载的资源包格式
        loader - 用于加载捆绑包的 ClassLoader
        reload - 表示捆绑重新加载的标志; true如果重新加载过期的资源包, false
        结果
        资源包实例,如果找不到, null
        异常
        NullPointerException -如果 bundleNamelocaleformat ,或 loadernull ,或者如果 null被返回 toBundleName
        IllegalArgumentException - 如果 format未知,或者找到给定参数的资源包含格式错误的数据。
        ClassCastException - 如果加载的类无法 ResourceBundleResourceBundle
        IllegalAccessException - 如果无法访问类或其无效构造函数。
        InstantiationException - 如果某个类的实例化因某些其他原因而失败。
        ExceptionInInitializerError - 如果此方法引发的初始化失败。
        SecurityException - 如果存在安全管理器并且拒绝创建新实例。 有关详细信息,请参阅Class.newInstance()
        IOException - 如果使用任何I / O操作读取资源时发生错误
        另请参见:
        ResourceBundleProvider.getBundle(String, Locale)
      • getTimeToLive

        public long getTimeToLive​(String baseName,
                                  Locale locale)
        返回在此ResourceBundle.Control下加载的资源包的生存时间(TTL)值。 正生存时间值指定捆绑包可以保留在缓存中的毫秒数,而不会根据构造它的源数据进行验证。 值0表示每次从缓存中检索包时都必须验证该包。 TTL_DONT_CACHE指定已加载的资源包未放入缓存中。 TTL_NO_EXPIRATION_CONTROL指定将已加载的资源包放入缓存中,但没有到期控制。

        到期仅影响ResourceBundle.getBundle工厂方法的捆绑加载过程。 也就是说,如果工厂方法在缓存中找到已过期的资源束,则工厂方法调用needsReload方法以确定是否需要重新加载资源束。 如果needsReload返回true ,则会从缓存中删除缓存的资源包实例。 否则,实例将保留在缓存中,并使用此方法返回的新TTL值进行更新。

        由于运行时环境的内存限制,所有缓存的资源包都将从缓存中删除。 返回大的正值并不意味着将加载的资源包锁定在缓存中。

        默认实现返回TTL_NO_EXPIRATION_CONTROL

        参数
        baseName - 为其指定过期值的资源束的基本名称。
        locale - 指定了到期值的资源包的区域设置。
        结果
        缓存时间(0或从缓存时间的正毫秒偏移量)到缓存中已加载的包已过期, TTL_NO_EXPIRATION_CONTROL用于禁用过期控制,或 TTL_DONT_CACHE用于禁用缓存。
        异常
        NullPointerException - 如果 baseNamelocalenull
      • needsReload

        public boolean needsReload​(String baseName,
                                   Locale locale,
                                   String format,
                                   ClassLoader loader,
                                   ResourceBundle bundle,
                                   long loadTime)
        确定是否需要根据loadTime或其他一些条件给出的加载时间重新加载缓存中已过期的bundle 如果需要重新加载,该方法返回true ; 否则为false loadTime是自Calendar Epoch以来的毫秒偏移量。

        调用ResourceBundle.getBundle工厂方法在用于其当前调用的ResourceBundle.Control实例上调用此方法,而不是在最初加载资源束的调用中使用的实例上调用此方法。

        默认实现比较loadTime以及资源束的源数据的上次修改时间。 如果确定源数据自loadTime以来已被修改,则返回true 否则,返回false 此实现假定给定的format与其文件后缀是相同的字符串,如果它不是默认格式之一, "java.class""java.properties"

        参数
        baseName - 资源包的基本包名称,完全限定的类名
        locale - 应为其实例化资源包的语言环境
        format - 要加载的资源包格式
        loader - 用于加载捆绑包的 ClassLoader
        bundle - 已在缓存中过期的资源包实例
        loadTime - bundle已加载并放入缓存的时间
        结果
        true如果需要重新加载过期的包; 否则为false
        异常
        NullPointerException -如果 baseNamelocaleformatloader ,或 bundlenull
      • toBundleName

        public String toBundleName​(String baseName,
                                   Locale locale)
        将给定的baseNamelocale转换为包名称。 newBundleneedsReload方法的默认实现调用此方法。

        此实现返回以下值:

          baseName + "_" + language + "_" + script + "_" + country + "_" + variant 
        其中, languagescriptcountryvariant是语言,脚本,国家和变量值locale分别。 空字符串的最终组件值与前面的“_”一起被省略。 当脚本为空时,脚本值与前面的“_”一起被省略。 如果所有值都是空字符串,则返回baseName

        例如,如果baseName"baseName"并且localeLocale("ja", "", "XX") ,则返回"baseName_ja_ _XX" 如果给定的区域设置为Locale("en") ,则返回"baseName_en"

        覆盖此方法允许应用程序在组织和本地化资源打包中使用不同的约定。

        参数
        baseName - 资源包的基本名称,完全限定的类名
        locale - 应为其加载资源包的语言环境
        结果
        资源包的包名称
        异常
        NullPointerException - 如果 baseNamelocalenull
        另请参见:
        AbstractResourceBundleProvider.toBundleName(String, Locale)
      • toResourceName

        public final String toResourceName​(String bundleName,
                                           String suffix)
        通过将'.'bundleName所有出现次数替换为'/'并附加'.'和给定文件suffix ,将给定的bundleName转换为ClassLoader.getResource方法所需的suffix 例如,如果bundleName"foo.bar.MyResources_ja_JP"suffix"properties" ,则返回"foo/bar/MyResources_ja_JP.properties"
        参数
        bundleName - 捆绑包名称
        suffix - 文件类型后缀
        结果
        转换后的资源名称
        异常
        NullPointerException - 如果 bundleNamesuffixnull