JAVA国际化---ResourceBundle使用
?
?
今天在工作中用到了ResourceBundle这个类,随手总结一下。
??? JDK文档中是这样说明它的:
??? 使用这种方式,可以编写很大程度上独立于用户语言环境的程序代码,它将资源包中大部分(即便不是全部)特定于语言环境的信息隔离开来。
- 轻松地本地化或翻译成不同的语言一次处理多个语言环境以后可以轻松进行修改,以便支持更多的语言环境
?????我在这里只说一种用法。ResourceBundle提供了两个直接子类ListResourceBundle, PropertyResourceBundle,我们这里没有使用这两个直接子类,而是直接继承了ResourceBundle自己重写了一个基础类,因为ResourceBundle为抽象类所以必须实现handleGetObject 和 getKeys()这两方法。
?
ListResourceBundle
????? 同样也是一个抽象类,不过他已经实现了handleGetObject 和 getKeys()这两个在ResourceBundle声明的方法,ListResourceBundle的虚方法为protected abstract Object[][] getContents(),必须返回一个用于表示键值对的二维数组。个人认为比较特别,所以我们不使用这个类。顺便说一句ListResourceBundle也有一个直接子类AccessibleResourceBundle,不过在JDK1.3已经过时了。
PropertyResourceBundle
?????? 它包括两个构造方法,PropertyResourceBundle(InputStream stream)和PropertyResourceBundle(Reader reader) ,我们可以很方便的读取来自.properties文件的资源。
?
?????? 不过笔者不打算使用这两个直接子类做任何事情,笔者还是选择新写一个ResourceBundle的子类(程序版权属于笔者公司,只说思路不贴源码)。在这个新类中我们会定义三个成员变量,一个用于缓存读入的Properties,我们给它的声明为static private ConcurrentHashMap<String, Properties> hashMapLocaleToProps;一个用于保存当前的Properties,我们给他的声明为private Properties props;最后一个变量private final Locale locale 用于表示当前的语言环境。
- 构造方法:首先从配置文件、DB或者其他任何地方读到当前语言环境配置,姑且保存在局部变量language,笔者把它作为构造方法的参数传入locale = new Locale(language)。接下来我们从hashMapLocaleToProps中查找该资源文件是否已经被缓存,props=hashMapLocaleToProps.get(locale.toString()),如果已经存在则直接return等待getKeys()或者handleGetObject(String sKey)的调用(这两个必须重写的方法随后我会给出简单的源码便于读者理解);如果缓存中没有找到则直接去文件中读取,用什么方法读取都可以。笔者使用的方法为:先由locale.toString()拼成完整的资源文件目录:sFileName。
FileInputStream is = new FileInputStream(sFileName);m_props.load(is);getKeys():
@Override public Enumeration getKeys() { return props.keys(); }?handleGetObject(String sKey):??? @Overridepublic Object handleGetObject(String sKey) { String sVal = props.getProperty(sKey); return sVal; }基础类就算写好了,下面我们可以写不同语言的资源包的类了,他们将都继承这个基础类。我们把baseName命名为testResourceBundle。我们接下来写两个资源包类
public class testResourceBundle_zh_CN extends testResourceBundleBase{ public testResourceBundle_zh_CN() { super("zh_CN"); }}?public class testResourceBundle extends testResourceBundleBase{ public testResourceBundle() { super("zh"); }} ?看很简单吧。
对了还需要编写以baseName命名的默认资源包类testResourceBundle
?
接下来就是使用了
ResourceBundle rb = ResourceBundle.getBundle(sBundle, locale);String resource = rb.getString(sKey);
?到这里resource就是你要的经过本地化的资源了,现在你可以使用它了。看到这里可能有些朋友会感到迷惑了,感到迷惑的朋友可以去读读ResourceBundle.getBundle的源码,你的疑惑就会消失了。
?
文章中有什么不对的地方朋友们可以毫不留情的指出,希望能与大家交流。