- 封闭类:
ResourceBundle
ResourceBundle.Control 定义了一组回调方法,在捆绑加载过程中由 ResourceBundle.getBundle 工厂方法调用。换句话说,ResourceBundle.Control 与工厂方法协作以加载资源包。回调方法的默认实现提供工厂方法执行 默认行为 所需的信息。
ResourceBundle.Control 专为部署在未命名模块中的应用程序而设计,例如支持非标准格式的资源包或以非传统约定打包本地化资源。 ResourceBundleProvider 是迁移到模块时 ResourceBundle.Control 的替代品。当调用带有 ResourceBundle.Control 参数的工厂方法时,将抛出 UnsupportedOperationException。
除了回调方法之外,toBundleName 和toResourceName 方法的定义主要是为了方便实现回调方法。但是,可以覆盖 toBundleName 方法以在本地化资源的组织和打包方面提供不同的约定。 toResourceName 方法是 final 以避免使用错误的资源和类名分隔符。
getControl(List) 和 getNoFallbackControl(List) 两个工厂方法提供了 ResourceBundle.Control 实例来实现默认包加载过程的常见变体。
getFormats 方法返回的格式和 getCandidateLocales 方法返回的候选locale必须在同一基础包的所有 ResourceBundle.getBundle 调用中保持一致。否则,ResourceBundle.getBundle 方法可能会返回意外的包。例如,如果 getFormats 方法在第一次调用 ResourceBundle.getBundle 时仅返回 "java.class",而在第二次调用时仅返回 "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", Locale.forLanguageTag("fr-CH"),
ResourceBundle.Control.getControl(FORMAT_PROPERTIES));
给定 ResourceBundle.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 注意:
ResourceBundle.Control在命名模块中不受支持。如果在命名模块中调用带有ResourceBundle.Control的ResourceBundle.getBundle方法,该方法将抛出UnsupportedOperationException。ResourceBundleControlProvider的任何服务提供商在命名模块中都将被忽略。- 自从:
- 1.6
- 参见:
-
字段摘要
字段修饰符和类型Field描述仅类格式List包含"java.class"。默认格式List,其中按顺序包含字符串"java.class"和"java.properties"。仅属性格式List包含"java.properties"。static final long不缓存已加载资源包实例的生存时间常量。static final long用于禁用缓存中已加载资源包实例的过期控制的生存时间常量。 -
构造方法总结
构造方法 -
方法总结
修饰符和类型方法描述getCandidateLocales(String baseName, Locale locale) 返回Locale的List作为baseName和locale的候选locale。static final ResourceBundle.ControlgetControl(List<String> formats) getFallbackLocale(String baseName, Locale locale) 返回一个Locale用作后备locale,以供ResourceBundle.getBundle工厂方法进一步搜索资源包。getFormats(String baseName) 返回String的List包含用于为给定的baseName加载资源包的格式。static final ResourceBundle.ControlgetNoFallbackControl(List<String> formats) longgetTimeToLive(String baseName, Locale locale) 返回在此ResourceBundle.Control下加载的资源包的生存时间 (TTL) 值。booleanneedsReload(String baseName, Locale locale, String format, ClassLoader loader, ResourceBundle bundle, long loadTime) 根据loadTime给定的加载时间或其他一些标准,确定缓存中过期的bundle是否需要重新加载。newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) 为给定格式和locale的给定包名称实例化资源包,必要时使用给定的类加载器。toBundleName(String baseName, Locale locale) 将给定的baseName和locale转换为包名称。final StringtoResourceName(String bundleName, String suffix) 通过将bundleName中出现的所有'.'替换为'/'并附加'.'和给定文件suffix,将给定的bundleName转换为ClassLoader.getResource方法所需的形式。
-
字段详细信息
-
FORMAT_DEFAULT
默认格式List,其中按顺序包含字符串"java.class"和"java.properties"。这个List是不可修改的。- 参见:
-
FORMAT_CLASS
仅类格式List包含"java.class"。这个List是不可修改的。- 参见:
-
FORMAT_PROPERTIES
仅属性格式List包含"java.properties"。这个List是不可修改的。- 参见:
-
TTL_DONT_CACHE
public static final long TTL_DONT_CACHE不缓存已加载资源包实例的生存时间常量。- 参见:
-
TTL_NO_EXPIRATION_CONTROL
public static final long TTL_NO_EXPIRATION_CONTROL用于禁用缓存中已加载资源包实例的过期控制的生存时间常量。- 参见:
-
-
构造方法详细信息
-
Control
protected Control()唯一的构造方法。 (对于子类构造方法的调用,通常是隐式的。)
-
-
方法详情
-
getControl
返回一个ResourceBundle.Control,其中getFormats方法返回指定的formats。formats必须等于FORMAT_PROPERTIES、FORMAT_CLASS或FORMAT_DEFAULT之一。ResourceBundle.Control此方法返回的实例是单例且线程安全的。指定
FORMAT_DEFAULT等同于实例化ResourceBundle.Control类,只是此方法返回一个单例。- 参数:
formats-ResourceBundle.Control.getFormats方法返回的格式- 返回:
-
一个
ResourceBundle.Control支持指定的formats - 抛出:
NullPointerException- 如果formats是nullIllegalArgumentException- 如果formats未知
-
getNoFallbackControl
返回一个ResourceBundle.Control,其中getFormats方法返回指定的formats,getFallbackLocale方法返回null。formats必须等于FORMAT_PROPERTIES、FORMAT_CLASS或FORMAT_DEFAULT之一。ResourceBundle.Control此方法返回的实例是单例且线程安全的。- 参数:
formats-ResourceBundle.Control.getFormats方法返回的格式- 返回:
-
一个
ResourceBundle.Control支持指定的formats没有回退Locale支持 - 抛出:
NullPointerException- 如果formats是nullIllegalArgumentException- 如果formats未知
-
getFormats
返回String的List包含用于为给定的baseName加载资源包的格式。ResourceBundle.getBundle工厂方法尝试按照列表指定的顺序加载格式的资源包。此方法返回的列表必须至少有一个String。基于类的资源包的预定义格式为"java.class",基于属性 的预定义格式为"java.properties"。以"java."开头的字符串保留用于将来的扩展,不得由应用程序定义的格式使用。不需要返回不可变(不可修改)
List。但是,返回的List在被getFormats返回后不得发生变化。默认实现返回
FORMAT_DEFAULT以便ResourceBundle.getBundle工厂方法查找第一个基于类的资源包,然后是基于属性的资源包。- 参数:
baseName- 资源包的基本名称,一个完全限定的类名- 返回:
String的List包含用于加载资源包的格式。- 抛出:
NullPointerException- 如果baseName为空- 参见:
-
getCandidateLocales
返回Locale的List作为baseName和locale的候选locale。每当工厂方法尝试为目标Locale查找资源包时,ResourceBundle.getBundle工厂方法就会调用此方法。候选locale的顺序也对应于运行时资源查找路径(也称为母链),如果候选locale的相应资源包存在,并且它们的父级不是由加载的资源包本身定义的。如果希望将基础包作为父链的终端,列表的最后一个元素必须是根locale。
如果给定的区域设置等于
Locale.ROOT(根区域设置),则必须返回仅包含根Locale的List。在这种情况下,ResourceBundle.getBundle工厂方法仅加载基础包作为结果资源包。不需要返回不可变(不可修改)
List。但是,返回的List在被getCandidateLocales返回后不得发生变化。默认实现使用下面描述的规则返回包含
Locale的List。在下面的描述中, L 、 S 、 C 和 V 分别代表非空语言、脚本、国家和变体。例如,[L , C ] 代表一个Locale,它只对语言和国家有非空值。 L("xx") 的形式表示(非空)语言值是"xx"。对于所有情况,省略最终组件值为空字符串的Locales。- 对于具有空脚本值的输入
Locale,通过一个一个地省略最终组件来附加候选Locales,如下所示:- [L , C , V ]
- [L , C ]
- [L]
Locale.ROOT
- 对于具有非空脚本值的输入
Locale,通过省略最后一个组件来附加候选Locales,然后附加从Locale生成的候选,并恢复国家和变体:- [L, S, C, V]
- [L, S, C]
- [L , S ]
- [L , C , V ]
- [L , C ]
- [L]
Locale.ROOT
- 对于具有由下划线分隔的多个子标签组成的变量值的输入
Locale,通过一个一个地省略变量子标签来生成候选Locales,然后在原始列表中每次出现具有完整变量值的Locales 之后插入它们。例如,如果变体由两个子标签 V1 和 V2 组成:- [L, S, C, V1, V2]
- [L, S, C, V1]
- [L, S, C]
- [L , S ]
- [L, C, V1, V2]
- [L, C, V1]
- [L , C ]
- [L]
Locale.ROOT
- 中文的特殊情况。当输入
Locale具有语言“zh”(中文)和空脚本值时,可能会提供“Hans”(简体)或“Hant”(繁体),具体取决于国家/地区。当国家是“CN”(中国)或“SG”(新加坡)时,提供“Hans”。当国家是“HK”(中国香港特别行政区)、“MO”(中国澳门特别行政区)或“TW”(台湾)时,提供“Hant”。对于所有其他国家或国家为空时,不提供脚本。例如,对于Locale("zh", "CN"),候选列表将是:- [L(“zh”),S(“汉斯”),C(“CN”)]
- [L(“zh”),S(“汉斯”)]
- [L(“zh”),C(“CN”)]
- [L(“zh”)]
Locale.ROOT
Locale("zh", "TW"),候选列表将是:- [L(“zh”),S(“汉”),C(“台湾”)]
- [L(“zh”),S(“汉特”)]
- [L(“zh”),C(“TW”)]
- [L(“zh”)]
Locale.ROOT
- 挪威语的特例。
Locale("no", "NO", "NY")和Locale("nn", "NO")都代表 Norwegian Nynorsk。当locale的语言是“nn”时,标准候选列表生成到 [L ("nn")],然后添加以下候选:- [L(“否”),C(“否”),V(“纽约”)]
- [L(“否”),C(“否”)]
- [L(“否”)]
Locale.ROOT
Locale("no", "NO", "NY"),则首先将其转换为Locale("nn", "NO"),然后执行上述过程。此外,Java 将语言“no”视为挪威语“nb”的同义词。除了单个案例
Locale("no", "NO", "NY")(上面处理过),当输入Locale具有语言“no”或“nb”时,具有语言代码“no”和“nb”的候选Locales 被交错,首先使用请求的语言,然后使用其代名词。例如,Locale("nb", "NO", "POSIX")生成以下候选列表:- [L(“nb”),C(“否”),V(“POSIX”)]
- [L(“否”),C(“否”),V(“POSIX”)]
- [L(“NB”),C(“否”)]
- [L(“否”),C(“否”)]
- [L ("nb")]
- [L(“否”)]
Locale.ROOT
Locale("no", "NO", "POSIX")将生成相同的列表,只是带有“no”的locale会出现在带有“nb”的相应locale之前。
默认实现使用
ArrayList,重写实现可以在将其返回给调用者之前对其进行修改。但是,getCandidateLocales返回后,子类不得修改它。例如,如果给定的
baseName是“消息”并且给定的locale是Locale("ja", "", "XX"),那么Locale的List:Locale("ja", "", "XX") Locale("ja") Locale.ROOT被返回。如果找到“ja”和“”Locale的资源包,则运行时资源查找路径(父链)为:Messages_ja -> Messages- 参数:
baseName- 资源包的基本名称,一个完全限定的类名locale- 需要资源包的locale- 返回:
-
对于给定的
locale,候选Locale的List - 抛出:
NullPointerException- 如果baseName或locale是null
- 对于具有空脚本值的输入
-
getFallbackLocale
返回一个Locale用作后备locale,以供ResourceBundle.getBundle工厂方法进一步搜索资源包。每次未找到baseName和locale的结果资源包时,都会从工厂方法调用此方法,其中 locale 是ResourceBundle.getBundle的参数或此方法返回的先前后备locale。如果不需要进一步的回退搜索,该方法返回
null。如果给定的
locale不是默认实现,则默认实现返回 默认Locale。否则,返回null。- 参数:
baseName- 资源包的基本名称,ResourceBundle.getBundle无法为其找到任何资源包(基本包除外)的完全限定类名locale-ResourceBundle.getBundle无法找到任何资源包的Locale(基础包除外)- 返回:
Locale用于后备搜索,或者null如果不需要进一步的后备搜索。- 抛出:
NullPointerException- 如果baseName或locale是null
-
newBundle
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IllegalAccessException , InstantiationException , IOException 为给定格式和locale的给定包名称实例化资源包,必要时使用给定的类加载器。如果没有可用于给定参数的资源包,则此方法返回null。如果由于意外错误而无法实例化资源包,则必须通过抛出Error或Exception而不是简单地返回null来报告错误。如果
reload标志为true,则表明正在调用此方法,因为之前加载的资源包已过期。- 实现要求:
-
命名模块中的资源包受
Module.getResourceAsStream指定的封装规则的约束。当资源包对应的资源文件的包无条件打开时,指定类加载器可见的命名模块中的资源包是可访问的。默认实现实例化一个
ResourceBundle如下。- 捆绑名称是通过调用
toBundleName(baseName, locale)获得的。 - 如果
format是"java.class",则使用给定的类加载器加载包名称指定的Class。如果找到并可访问Class,则实例化ResourceBundle。如果bundle类文件的包被无条件打开,则资源bundle是可访问的;否则,将抛出IllegalAccessException。请注意,在这个默认实现中,reload标志在加载基于类的资源包时被忽略。 - 如果
format是"java.properties",则调用toResourceName(bundlename, "properties")以获取资源名称。如果reload是true,则调用load.getResource以获取URL以创建URLConnection。这个URLConnection用于底层资源加载层的禁用缓存,以及得到一个InputStream。否则,将调用loader.getResourceAsStream以获取InputStream。然后,用InputStream构造一个PropertyResourceBundle。 - 如果
format既不是"java.class"也不是"java.properties",则抛出IllegalArgumentException。 - 如果
locale的语言是 遗留语言代码 中的一种,无论是旧的还是新的,然后在需要时重复加载过程,并使用另一种语言的包名称。例如,“iw”代表“他”,反之亦然。
- 捆绑名称是通过调用
- 参数:
baseName- 资源包的基本包名,一个完全限定的类名locale- 应该为其实例化资源包的localeformat- 要加载的资源包格式loader- 用于加载包的ClassLoaderreload- 指示捆绑包重新加载的标志;true如果重新加载过期的资源包,false否则- 返回:
-
资源包实例,如果找不到则返回
null。 - 抛出:
NullPointerException- 如果bundleName、locale、format或loader是null,或者如果null由toBundleName返回IllegalArgumentException- 如果format未知,或者如果为给定参数找到的资源包含格式错误的数据。ClassCastException- 如果加载的类不能转换为ResourceBundleIllegalAccessException- 如果类或其 nullary 构造函数不可访问。InstantiationException- 如果某个类的实例化由于其他原因而失败。ExceptionInInitializerError- 如果此方法引发的初始化失败。SecurityException- 如果存在安全管理器并且拒绝创建新实例。有关详细信息,请参阅Class.newInstance()。IOException- 如果在使用任何 I/O 操作读取资源时发生错误- 参见:
-
getTimeToLive
返回在此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- 如果baseName或locale是null
-
needsReload
public boolean needsReload(String baseName, Locale locale, String format, ClassLoader loader, ResourceBundle bundle, long loadTime) 根据loadTime给定的加载时间或其他一些标准,确定缓存中过期的bundle是否需要重新加载。如果需要重新加载,该方法返回true;false否则。loadTime是自Calendar纪元 以来的毫秒偏移量。调用
ResourceBundle.getBundle工厂方法在用于其当前调用的ResourceBundle.Control实例上调用此方法,而不是在最初加载资源包的调用中使用的实例上。默认实现比较
loadTime和资源包源数据的最后修改时间。如果确定源数据自loadTime以来已被修改,则返回true。否则,返回false。如果给定的format不是默认格式之一,即"java.class"或"java.properties",则此实现假定给定的format与其文件后缀相同。- 参数:
baseName- 资源包的基本包名,一个完全限定的类名locale- 应该为其实例化资源包的localeformat- 要加载的资源包格式loader- 用于加载包的ClassLoaderbundle- 缓存中已过期的资源包实例loadTime-bundle加载并放入缓存的时间- 返回:
true如果过期的包需要重新加载;false否则。- 抛出:
NullPointerException- 如果baseName、locale、format、loader或bundle是null
-
toBundleName
将给定的baseName和locale转换为包名称。此方法从newBundle和needsReload方法的默认实现中调用。此实现返回以下值:
baseName + "_" + language + "_" + script + "_" + country + "_" + variant
其中language、script、country和variant分别是locale的语言、脚本、国家和变体值。空字符串的最终组件值与前面的“_”一起被省略。当脚本为空时,脚本值连同前面的“_”一起被省略。如果所有值都是空字符串,则返回baseName。例如,如果
baseName是"baseName"并且locale是Locale("ja", "", "XX"),则返回"baseName_ja_ _XX"。如果给定的locale是Locale("en"),则返回"baseName_en"。重写此方法允许应用程序在本地化资源的组织和打包中使用不同的约定。
- 参数:
baseName- 资源包的基本名称,一个完全限定的类名locale- 应为其加载资源包的locale- 返回:
- 资源包的包名称
- 抛出:
NullPointerException- 如果baseName或locale是null- 参见:
-
toResourceName
通过将bundleName中出现的所有'.'替换为'/'并附加'.'和给定文件suffix,将给定的bundleName转换为ClassLoader.getResource方法所需的形式。例如,如果bundleName是"foo.bar.MyResources_ja_JP"并且suffix是"properties",则返回"foo/bar/MyResources_ja_JP.properties"。- 参数:
bundleName- 包名称suffix- 文件类型后缀- 返回:
- 转换后的资源名称
- 抛出:
NullPointerException- 如果bundleName或suffix是null
-