public abstract class ResourceBundle
extends Object
Resource bundles contain locale-specific objects. When your program needs a locale-specific resource, a String 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. This allows you to write programs that can: be easily localized, or translated, into different languages 
handle multiple locales at once 
be easily modified later to support even more locales 
One resource bundle is, conceptually, a set of related classes that inherit from ResourceBundle. Each related subclass of ResourceBundle has the same base name plus an additional component that identifies its locale. For example, suppose your resource bundle is named MyResources. The first class you are likely to write is the default resource bundle which simply has the same name as its family--MyResources. You can also provide as many related locale-specific classes as you need: for example, perhaps you would provide a German one named MyResources_de. Each related subclass of ResourceBundle contains the same items, but the items have been translated for the locale represented by that ResourceBundle subclass. For example, both MyResources and MyResources_de may have a String that's used on a button for canceling operations. In MyResources the String may contain Cancel and in MyResources_de it may contain Abbrechen. If there are different resources for different countries, you can make specializations: for example, MyResources_de_CH is the German language (de) in Switzerland (CH). If you want to only modify some of the resources in the specialization, you can do so. When your program needs a locale-specific object, it loads the ResourceBundle class using the getBundle method:  ResourceBundle myResources =
      ResourceBundle.getBundle("MyResources", currentLocale);
 
The first argument specifies the family name of the resource bundle that contains the object in question. The second argument indicates the desired locale. getBundle uses these two arguments to construct the name of the ResourceBundle subclass it should load as follows. 
The resource bundle lookup searches for classes with various suffixes on the basis of (1) the desired locale and (2) the current default locale as returned by Locale.getDefault(), and (3) the root resource bundle (baseclass), in the following order from lower-level (more specific) to parent-level (less specific): baseclass + "_" + language1 + "_" + country1 + "_" + variant1 
baseclass + "_" + language1 + "_" + country1 + "_" + variant1 + ".properties" 
baseclass + "_" + language1 + "_" + country1 
baseclass + "_" + language1 + "_" + country1 + ".properties" 
baseclass + "_" + language1 
baseclass + "_" + language1 + ".properties" 
baseclass + "_" + language2 + "_" + country2 + "_" + variant2 
baseclass + "_" + language2 + "_" + country2 + "_" + variant2 + ".properties" 
baseclass + "_" + language2 + "_" + country2 
baseclass + "_" + language2 + "_" + country2 + ".properties" 
baseclass + "_" + language2 
baseclass + "_" + language2 + ".properties" 
baseclass 
baseclass + ".properties" For example, if the current default locale is en_US, the locale the caller is interested in is fr_CH, and the resource bundle name is MyResources, resource bundle lookup will search for the following classes, in order: 
MyResources_fr_CH 
MyResources_fr 
MyResources_en_US 
MyResources_en 
MyResources The result of the lookup is a class, but that class may be backed by a properties file on disk. That is, if getBundle does not find a class of a given name, it appends ".properties" to the class name and searches for a properties file of that name. If it finds such a file, it creates a new PropertyResourceBundle object to hold it. Following on the previous example, it will return classes and and files giving preference as follows: (class) MyResources_fr_CH (file) MyResources_fr_CH.properties (class) MyResources_fr (file) MyResources_fr.properties (class) MyResources_en_US (file) MyResources_en_US.properties (class) MyResources_en (file) MyResources_en.properties (class) MyResources (file) MyResources.properties If a lookup fails, getBundle() throws a MissingResourceException. The baseclass must be fully qualified (for example, myPackage.MyResources, not just MyResources). It must also be accessable by your code; it cannot be a class that is private to the package where ResourceBundle.getBundle is called. Note: ResourceBundles are used internally in accessing NumberFormats, Collations, and so on. The lookup strategy is the same. Resource bundles contain key/value pairs. The keys uniquely identify a locale-specific object in the bundle. Here's an example of a ListResourceBundle that contains two key/value pairs:  class MyResource extends ListResourceBundle {
      public Object[][] getContents() {
              return contents;
      }
      static final Object[][] contents = {
      // LOCALIZE THIS
              {"OkKey", "OK"},
              {"CancelKey", "Cancel"},
      // END OF MATERIAL TO LOCALIZE
      };
 }
 
Keys are always Strings. In this example, the keys are OkKey and CancelKey. In the above example, the values are also Strings--OK and Cancel--but they don't have to be. The values can be any type of object. 
You retrieve an object from resource bundle using the appropriate getter method. Because OkKey and CancelKey are both strings, you would use getString to retrieve them:  button1 = new Button(myResourceBundle.getString("OkKey"));
 button2 = new Button(myResourceBundle.getString("CancelKey"));
 
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 MissingResourceException. 
Besides getString; ResourceBundle supports a number of other methods for getting different types of objects such as getStringArray. If you don't have an object that matches one of these methods, you can use getObject and cast the result to the appropriate type. For example:  int[] myIntegers = (int[]) myResources.getObject("intList");
 
NOTE: 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. In fact, you must provide all of the classes in any given inheritance chain that you provide a resource for. For example, if you provide MyResources_fr_BE, you must provide both MyResources and MyResources_fr or the resource bundle lookup won't work right. The Java 2 platform provides two subclasses of ResourceBundle, ListResourceBundle and PropertyResourceBundle, 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 previous example, ListResourceBundle manages its resource as a List of key/value pairs. PropertyResourceBundle uses a properties file to manage its resources. If ListResourceBundle or PropertyResourceBundle do not suit your needs, you can write your own ResourceBundle subclass. Your subclasses must override two methods: handleGetObject and getKeys(). The following is a very simple example of a ResourceBundle subclass, MyResources, that manages two resources (for a larger number of resources you would probably use a Hashtable). Notice that if the key is not found, handleGetObject must return null. If the key is null, a NullPointerException should be thrown. Notice also that you don't need to supply a value if a "parent-level" ResourceBundle handles the same key with the same value (as in United Kingdom below). Also notice that because you specify an en_GB resource bundle, you also have to provide a default en resource bundle even though it inherits all its data from the root resource bundle. Example:  // default (English language, United States)
 abstract class MyResources extends ResourceBundle {
     public Object handleGetObject(String key) {
         if (key.equals("okKey")) return "Ok";
         if (key.equals("cancelKey")) return "Cancel";
     return null;
     }
 } // German language
 public class MyResources_de extends MyResources {
     public Object handleGetObject(String key) {
         // don't need okKey, since parent level handles it.
         if (key.equals("cancelKey")) return "Abbrechen";
         return null;
     }
 }
 
You do not have to restrict yourself to using a single family of ResourceBundles. For example, you could have a set of bundles for exception messages, ExceptionResources (ExceptionResources_fr, ExceptionResources_de, ...), and one for widgets, WidgetResource (WidgetResources_fr, WidgetResources_de, ...); breaking up the resources however you like. 

解决方案 »

  1.   

    ResourceBundle 有点象Windows 编程中的 Stringtable 资源一样,其目的都是使应用更方便地国际化,比如一个Button 上面应该显示的 Label 如果在英文环境下为 "OK" 的话,在中文环境下为 "确定",这个工作可以由 ResourceBundle 根据平台的不同在相应平台的资源文件中查找出的字符串来设置 Label 完成。
      

  2.   

    Thank backlove(bingo) and luodi  !