resourcebundle.java

来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 539 行 · 第 1/2 页

JAVA
539
字号
/*
 * @(#)ResourceBundle.java	1.22 98/01/20
 *
 * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
 * (C) Copyright IBM Corp. 1996 - All Rights Reserved
 *
 * Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
 *
 *   The original version of this source code and documentation is copyrighted
 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
 * materials are provided under terms of a License Agreement between Taligent
 * and Sun. This technology is protected by multiple US and International
 * patents. This notice and attribution to Taligent may not be removed.
 *   Taligent is a registered trademark of Taligent, Inc.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL purposes and without
 * fee is hereby granted provided that this copyright notice
 * appears in all copies. Please refer to the file "copyright.html"
 * for further important copyright and licensing information.
 *
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 *
 */
package java.util;

import java.io.InputStream;
import java.io.FileInputStream;
import java.util.Hashtable;

/**
 *
 * Resource bundles contain locale-specific objects.
 * When your program needs a locale-specific resource,
 * a <code>String</code> for example, your program can load it
 * from the resource bundle that is appropriate for the
 * current user's locale. In this way, you can write
 * program code that is largely independent of the user's
 * locale isolating most, if not all, of the locale-specific
 * information in resource bundles.
 *
 * <p>
 * This allows you to write programs that can:
 * <UL type=SQUARE>
 * <LI> be easily localized, or translated, into different languages
 * <LI> handle multiple locales at once
 * <LI> be easily modified later to support even more locales
 * </UL>
 *
 * <P>
 * One resource bundle is, conceptually, a set of related classes that
 * inherit from <code>ResourceBundle</code>. Each related subclass of
 * <code>ResourceBundle</code> has the same base name plus an additional
 * component that identifies its locale. For example, suppose your resource
 * bundle is named <code>MyResources</code>. The first class you are likely
 * to write is the default resource bundle which simply has the same name as
 * its family--<code>MyResources</code>. You can also provide as
 * many related locale-specific classes as you need: for example, perhaps
 * you would provide a German one named <code>MyResources_de</code>.
 *
 * <P>
 * Each related subclass of <code>ResourceBundle</code> contains the same
 * items, but the items have been translated for the locale represented by that
 * <code>ResourceBundle</code> subclass. For example, both <code>MyResources</code>
 * and <code>MyResources_de</code> may have a <code>String</code> that's used
 * on a button for confirming operations. In <code>MyResources</code> the
 * <code>String</code> may contain <code>OK</code> and in
 * <code>MyResources_de</code> it may contain <code>Gut</code>.
 *
 * <P>
 * If there are different resources for different countries, you
 * can make specializations: for example, <code>MyResources_de_CH</code>
 * for Switzerland. If you want to only modify some of the resources
 * in the specialization, you can do so.
 *
 * <P>
 * When your program needs a locale-specific object, it loads
 * the <code>ResourceBundle</code> class using the <code>getBundle</code>
 * method:
 * <blockquote>
 * <pre>
 * ResourceBundle myResources =
 *      ResourceBundle.getBundle("MyResources", currentLocale);
 * </pre>
 * </blockquote>
 * The first argument specifies the family name of the resource
 * bundle that contains the object in question. The second argument
 * indicates the desired locale. <code>getBundle</code>
 * uses these two arguments to construct the name of the
 * <code>ResourceBundle</code> subclass it should load as follows.
 *
 * <P>
 * The resource bundle lookup searches for classes with various suffixes
 * on the basis of (1) the desired locale and (2) the default locale (baseclass),
 * in the following order from lower-level (more specific) to parent-level
 * (less specific):
 * <p> baseclass + "_" + language1 + "_" + country1 + "_" + variant1
 * <BR> baseclass + "_" + language1 + "_" + country1
 * <BR> baseclass + "_" + language1
 * <BR> baseclass
 * <BR> baseclass + "_" + language2 + "_" + country2 + "_" + variant2
 * <BR> baseclass + "_" + language2 + "_" + country2
 * <BR> baseclass + "_" + language2
 *
 * <P>
 * The result of the lookup is a class, but that class may be
 * backed by a property file on disk. If a lookup fails,
 * <code>getBundle()</code> throws a <code>MissingResourceException</code>.
 *
 * <P>
 * The baseclass <strong>must</strong> be fully
 * qualified (for example, <code>myPackage.MyResources</code>, not just
 * <code>MyResources</code>). It must
 * also be accessable by your code; it cannot be a class that is private
 * to the package where <code>ResourceBundle.getBundle</code> is called.
 *
 * <P>
 * Note: <code>ResourceBundle</code> are used internally in accessing
 * <code>NumberFormat</code>s, <code>Collation</code>s, and so on.
 * The lookup strategy is the same.
 *
 * <P>
 * Resource bundles contain key/value pairs. The keys uniquely
 * identify a locale-specific object in the bundle. Here's an
 * example of a <code>ListResourceBundle</code> that contains
 * two key/value pairs:
 * <blockquote>
 * <pre>
 * class MyResource extends ListResourceBundle {
 *      public Object[][] getContents() {
 *              return contents;
 *      }
 *      static final Object[][] contents = {
 *      // LOCALIZE THIS
 *              {"OkKey", "OK"},
 *              {"CancelKey", "Cancel"},
 *      // END OF MATERIAL TO LOCALIZE
 *      };
 * }
 * </pre>
 * </blockquote>
 * Keys are always <code>String</code>s.
 * In this example, the keys are <code>OkKey</code> and <code>CancelKey</code>.
 * In the above example, the values
 * are also <code>String</code>s--<code>OK</code> and <code>Cancel</code>--but
 * they don't have to be. The values can be any type of object.
 *
 * <P>
 * You retrieve an object from resource bundle using the appropriate
 * getter method. Because <code>OkKey</code> and <code>CancelKey</code>
 * are both strings, you would use <code>getString</code> to retrieve them:
 * <blockquote>
 * <pre>
 * button1 = new Button(myResourceBundle.getString("OkKey"));
 * button2 = new Button(myResourceBundle.getString("CancelKey"));
 * </pre>
 * </blockquote>
 * The getter methods all require the key as an argument and return
 * the object if found. If the object is not found, the getter method
 * throws a <code>MissingResourceException</code>.
 *
 * <P>
 * Besides <code>getString</code>; ResourceBundle supports a number
 * of other methods for getting different types of objects such as
 * <code>getStringArray</code>. If you don't have an object that
 * matches one of these methods, you can use <code>getObject</code>
 * and cast the result to the appropriate type. For example:
 * <blockquote>
 * <pre>
 * int[] myIntegers = (int[]) myResources.getObject("intList");
 * </pre>
 * </blockquote>
 *
 * <P>
 * <STRONG>NOTE:</STRONG> You should always supply a baseclass with
 * no suffixes. This will be the class of "last resort", if a locale
 * is requested that does not exist. For example, below we have a class
 * <code>MyResources</code>. It happens to contain US strings,
 * so we don't have to have an explicit <code>MyResource_en</code> or
 * <code>MyResource_en_US</code>.
 *
 * <P>
 * The JDK provides two subclasses of <code>ResourceBundle</code>,
 * <code>ListResourceBundle</code> and <code>PropertyResourceBundle</code>,
 * that provide a fairly simple way to create resources. (Once serialization
 * is fully integrated, we will provide another
 * way.) As you saw briefly in a prevous example, <code>ListResourceBundle</code>
 * manages its resource as a List of key/value pairs.
 * <code>PropertyResourceBundle</code> uses a properties file to manage
 * its resources.
 *
 * <p>
 * If <code>ListResourceBundle</code> or <code>PropertyResourceBundle</code>
 * do not suit your needs, you can write your own <code>ResourceBundle</code>
 * subclass.  Your subclasses must overrde two methods: <code>handleGetObject</code>
 * and <code>getKeys()</code>.
 *
 * <P>
 * The following is a very simple example of a <code>ResourceBundle</code> subclass
 * that manages only a few resources (for a larger number of resources
 * you would probably use a <code>Hashtable</code>). Notice that if the key
 * is not found, <code>handleGetObject</code> must return null. Notice also
 * that you don't need to supply a value if a "parent-level"
 * <code>ResourceBundle</code> handles the same
 * key with the same value (look at uk below).
 * <strong><p>Example:</strong>
 * <blockquote>
 * <pre>
 * abstract class MyResources extends ResourceBundle {
 *     public Object handleGetObject(String key) {
 *         if (key.equals("okKey")) return "Ok";
 *         if (key.equals("cancelKey")) return "Cancel";
 * 	   return null;
 *     }
 * }
 *
 * abstract class MyResources_de extends MyResources {
 *     public Object handleGetObject(String key) {
 *         if (key.equals("okKey")) return "Gut";
 *         if (key.equals("cancelKey")) return "Vernichten";
 *         return null;
 *     }
 * }
 *
 * abstract class MyResources_uk extends MyResources {
 *     public Object handleGetObject(String key) {
 *         // don't need okKey, since parent level handles it.
 *         if (key.equals("cancelKey")) return "Dispose";
 *     	   return null;
 *     }
 * }
 * </pre>
 * </blockquote>
 * You do not have to restrict yourself to using a single family of
 * <code>ResourceBundle</code>s. For example, you could have a set of bundles for
 * exception messages, <code>ExceptionResources</code>
 * (<code>ExceptionResources_fr</code>, <code>ExceptionResources_de</code>, ...),
 * and one for widgets, <code>WidgetResource</code> (<code>WidgetResources_fr</code>,
 * <code>WidgetResources_de</code>, ...); breaking up the resources however you like.
 *
 * @see ListResourceBundle
 * @see PropertyResourceBundle
 * @see MissingResourceException
 */
abstract public class ResourceBundle {

    /**
     * Get an object from a ResourceBundle.
     * <BR>Convenience method to save casting.
     * @param key see class description.
     */
    public final String getString(String key) throws MissingResourceException {
        return (String) getObject(key);
    }

    /**
     * Get an object from a ResourceBundle.
     * <BR>Convenience method to save casting.
     * @param key see class description.
     */
    public final String[] getStringArray(String key)
        throws MissingResourceException {
        return (String[]) getObject(key);
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?