# 自定义资源包加载

> 原文： [https://docs.oracle.com/javase/tutorial/i18n/resbundle/control.html](https://docs.oracle.com/javase/tutorial/i18n/resbundle/control.html)

在本课程的前面部分，您已经学习了如何创建和访问`ResourceBundle`类的对象。本节将扩展您的知识并解释如何利用 [`ResourceBundle.Control`](https://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.Control.html) 类功能。

创建`ResourceBundle.Control`以指定如何定位和实例化资源包。它定义了一组回调方法，这些方法在捆绑加载过程中由 [`ResourceBundle.getBundle`](https://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String-java.util.Locale-java.util.ResourceBundle.Control-) 工厂方法调用。

与前面描述的 [`ResourceBundle.getBundle`](https://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String-java.util.Locale-) 方法不同，此`ResourceBundle.getBundle`方法使用指定的基本名称，默认语言环境和指定的控件定义资源包。

```
public static final ResourceBundle getBundle(
    String baseName,
    ResourceBundle.Control cont
    // ...

```

指定的控件提供资源包加载过程的信息。

以下示例程序 [`RBControl.java`](examples/RBControl.java) 说明了如何为中文语言环境定义自己的搜索路径。

## 1.创建`properties`文件。

如前所述，您可以从类或`properties`文件加载资源。这些文件包含以下语言环境的说明：

*   `[`RBControl.properties`](examples/RBControl.properties) `- 全球
*   `[`RBControl_zh.properties`](examples/RBControl_zh.properties) `- 仅限语言：简体中文
*   `[`RBControl_zh_cn.properties`](examples/RBControl_zh_CN.properties) `- 仅限地区：中国
*   `[`RBControl_zh_hk.properties`](examples/RBControl_zh_HK.properties) `- 仅限地区：香港
*   `[`RBControl_zh_tw.properties`](examples/RBControl_zh_TW.properties) `- 台湾

在此示例中，应用程序为香港地区创建新的区域设置。

## 2.创建`ResourceBundle`实例。

与上一节中的示例一样，此应用程序通过调用`getBundle`方法创建`ResourceBundle`实例：

```
private static void test(Locale locale) {
    ResourceBundle rb = ResourceBundle.getBundle(
                            "RBControl",
                            locale,
                            new ResourceBundle.Control() {
                                    // ...
                            }
                        );

```

`getBundle`方法使用 RBControl 前缀搜索`properties`文件。但是，此方法包含`Control`参数，该参数驱动搜索 Chineese 语言环境的过程。

## 3.调用`getCandidateLocales`方法

`getCandidateLocales`方法返回`Locales`对象的列表，作为基本名称和语言环境的候选语言环境。

```
new ResourceBundle.Control() {
    @Override
    public List<Locale> getCandidateLocales(
                            String baseName,
                            Locale locale) {
                // ...                                        
    }
}

```

默认实现返回`Locale`对象的列表，如下所示：Locale（语言，国家/地区）。

但是，重写此方法以实现以下特定行为：

```
if (baseName == null)
    throw new NullPointerException();

if (locale.equals(new Locale("zh", "HK"))) {
    return Arrays.asList(
               locale,
               Locale.TAIWAN,
               // no Locale.CHINESE here
               Locale.ROOT);
} else if (locale.equals(Locale.TAIWAN)) {
    return Arrays.asList(
               locale,
               // no Locale.CHINESE here
               Locale.ROOT);
}

```

请注意，候选语言环境序列的最后一个元素必须是根区域设置。

## 4.调用`test`类

为以下四种不同的语言环境调用`test`类：

```
public static void main(String[] args) {
    test(Locale.CHINA);
    test(new Locale("zh", "HK"));
    test(Locale.TAIWAN);
    test(Locale.CANADA);
}

```

## 5.运行示例程序

您将看到程序输出如下：

```
locale: zh_CN
        region: China
        language: Simplified Chinese
locale: zh_HK
        region: Hong Kong
        language: Traditional Chinese
locale: zh_TW
        region: Taiwan
        language: Traditional Chinese
locale: en_CA
        region: global
        language: English

```

请注意，新创建的分配了香港地区，因为它是在适当的`properties`文件中指定的。繁体中文被指定为台湾语言的语言。

在`RBControl`示例中没有使用`ResourceBundle.Control`类的另外两个有趣的方法，但它们值得提及。 `getTimeToLive`方法用于确定资源包在缓存中可以存在多长时间。如果缓存中资源包的时间限制已过期，则调用`needsReload`方法以确定是否需要重新加载资源包。