Module  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所需的信息。 Note that this class is not supported in named modules.

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

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

    在返回的格式getFormats由返回的方法和候选语言环境getCandidateLocales方法必须全部一致ResourceBundle.getBundle调用了同样的基本包。 否则, ResourceBundle.getBundle方法可能会返回意外的捆绑包。 例如,如果getFormats方法仅对"java.class"的第一次调用ResourceBundle.getBundle "java.properties" ,而第二次调用仅"java.properties" ,则第二次调用将返回在第一次调用期间已被缓存的基于类的一个。

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

    应用程序可以指定由getControl工厂方法返回的ResourceBundle.Control实例,或从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)); 
    鉴于exampleResourceBundle.getBundle描述中的资源束,此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 is not supported in named modules.如果在命名模块中调用了ResourceBundle.ControlResourceBundle.getBundle方法,则该方法将抛出一个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)
    • 构造方法详细信息

      • 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 但是,返回List不得它已被退回后,突变getFormats

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

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

        public List<Locale> getCandidateLocales​(String baseName,
                                                Locale locale)
        返回ListLocale作为baseNamelocale候选地区。 每次工厂方法尝试找到目标的资源束时,这种方法由ResourceBundle.getBundle工厂方法调用Locale

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

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

        不要求退回一个不可改变的(不可修改的) List 但是,返回List不得它已被退回后,突变getCandidateLocales

        默认实现使用下面描述的规则返回一个List其中包含Locale 在下面的描述中, LSCV分别表示非空语言,脚本,国家和变体。 例如,[ LC ]代表一个Locale ,它只对语言和国家有非空值。 形式L (“xx”)表示(非空)语言值为“xx”。 对于所有情况,其最终成分值为空字符串的Locale s被省略。

        1. 对于具有空脚本值的输入Locale ,通过省略最终组件逐个追加候选人Locale ,如下所示:
          • [ LCV ]
          • [ LC ]
          • [ L ]
          • Locale.ROOT
        2. 对于具有非空脚本值的输入Locale ,通过省略最终组件直到语言来追加候选人Locale s,然后追加从Locale生成的Locale国家和变式恢复:
          • [ LSCV ]
          • [ LSC ]
          • [ LS ]
          • [ LCV ]
          • [ LC ]
          • [ L ]
          • Locale.ROOT
        3. 对于具有由下划线分隔的多个子标签组成的变体值的输入Locale ,通过逐个省略变体子标记来生成候选人Locale ,然后在每次出现Locale s之后插入其原始列表中的完整变体值。 例如,如果变体由两个子标签V1V2组成
          • [ LSCV1V2 ]
          • [ LSCV1 ]
          • [ LSC ]
          • [ LS ]
          • [ LCV1V2 ]
          • [ LCV1 ]
          • [ LC ]
          • [ L ]
          • Locale.ROOT
        4. 中国特殊情况。 输入Locale具有语言“zh”(中文)和空字符值时,可能会根据国家/地区提供“汉斯”(简体)或“汉特”(繁体)。 当国家是“CN”(中国)或“SG”(新加坡)时,提供“汉斯”。 当国家是“HK”(中国香港特别行政区)时,提供“MO”(中国澳门特别行政区)或“TW”(台湾)“Hant”。 对于所有其他国家或国家/地区为空时,不提供脚本。 例如,对于Locale("zh", "CN") ,候选人名单将是:
          • [ L (“zh”), S (“Hans”), C (“CN”)]
          • [ L (“zh”), S (“汉斯”)]
          • [ 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 (“否”), 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具有语言“否”或“nb”时,具有语言代码“否”和“nb”的候选人Locale s被交织,首先使用所请求的语言,然后使用其代名词。 例如, Locale("nb", "NO", "POSIX")生成以下候选列表:

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

        默认实现使用一个ArrayList ,该替换实现可能会在将其返回给调用者之前进行修改。 但是,一个子类在getCandidateLocales返回后不能修改它。

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

          Locale("ja", "", "XX")
             Locale("ja")
             Locale.ROOT 
        被退回 并且如果找到“ja”和“” Locale的资源束,则运行时资源查找路径(父链)是:
           Messages_ja -> Messages  
        参数
        baseName - 资源包的基本名称,一个完全限定的类名
        locale - 需要资源束的区域设置
        结果
        一个 List候选人 Locale s给定的 locale
        异常
        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 - 如果加载的类不能转换为 ResourceBundle
        IllegalAccessException - 如果类或其nullary构造函数不可访问。
        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工厂方法的捆绑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 
        其中languagescriptcountry ,并variant是语言,脚本,国家和变量值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由所要求的形式ClassLoader.getResource通过更换所有出现的方法'.'bundleName'/'和追加'.'和给定的文件suffix 例如,如果bundleName"foo.bar.MyResources_ja_JP"suffix"properties" ,则返回"foo/bar/MyResources_ja_JP.properties"
        参数
        bundleName - 包名称
        suffix - 文件类型后缀
        结果
        转换的资源名称
        异常
        NullPointerException - 如果 bundleNamesuffixnull