ResourceBundle
这个类主要用来解决国际化和本地化问题。国际化和本地化可不是两个概念,两者都是一起出现的。可以说,国际化的目的就是为了实现本地化。比如对于“取消”,中文中我们使用“取消”来表示,而英文中我们使用“cancel”。若我们的程序是面向国际的(这也是软件发展的一个趋势),那么使用的人群必然是多语言环境的,实现国际化就非常有必要。而ResourceBundle可以帮助我们轻松完成这个任务:当程序需要一个特定于语言环境的资源时(如 String),程序可以从适合当前用户语言环境的资源包(大多数情况下也就是.properties文件)中加载它。这样可以编写很大程度上独立于用户语言环境的程序代码,它将资源包中大部分(即便不是全部)特定于语言环境的信息隔离
案例
新建资源文件。资源文件都必须是ISO-8859-1编码,因此,对于所有非西方语系的处理,都必须先将之转换为Java Unicode Escape格式。转换方法是通过JDK自带的工具native2ascii.
my_en_US.properties:cancelKey=cancel
my_zh_CN.properties:cancelKey=\u53D6\u6D88(取消)
my_zh.properties:cancelKey=\u53D6\u6D88zh(取消zh)
my.properties:cancelKey=\u53D6\u6D88default(取消default)
ResourceBundle resourceBundle = ResourceBundle.getBundle("my",Locale.getDefault());
String cancelKey = resourceBundle.getString("cancelKey");
System.out.println(cancelKey);
resourceBundle = ResourceBundle.getBundle("my", new Locale("zh", "CN"));
cancelKey = resourceBundle.getString("cancelKey");
System.out.println(cancelKey);
resourceBundle = ResourceBundle.getBundle("my", Locale.US);
cancelKey = resourceBundle.getString("cancelKey");
System.out.println(cancelKey);
resourceBundle = ResourceBundle.getBundle("my", Locale.GERMAN);
cancelKey = resourceBundle.getString("cancelKey");
System.out.println(cancelKey);
resourceBundle = ResourceBundle.getBundle("my");
for (String key : resourceBundle.keySet()) {
System.out.println(resourceBundle.getString(key));
}
//前面三个分别按照zh_CN,US,默认的结果输出,
// 第四个由于我们未定义GERMAN属性文件,这时ResourceBundle为我们提供了一个fallback(也就是一个备用方案),
// 这个备用方案就是根据当前系统的语言环境来得到的本地化信息。
// 所以若是找不到GERMAN的,之后就会去找CHINA了,所以找到了res_zh_CN.properties这个资源包。
// 最后一个是若有多个属性文件,可以按照Map的形式遍历,获得属性文件内的各个值。
参考:JAVA中ResourceBundle使用详解_OovEver的博客-优快云博客_resourcebundle
ListResourceBundle
ListResourceBundle是ResourceBundle的一个抽象子类,它使用List来管理区域设置的资源
案例
1.创建资源类,继承ListResourceBundle,重写getContents()方法。
在在src根目录下,即default包下面下创建三个文件,MyResource.java、MyResource_zh_CN.java、MyResource_en_US.java,必须在根目录下,不然加载不到。
public class MyResource extends ListResourceBundle {
Object[][] data = new Object[][]{{"cancel", "取消default"}};
@Override
protected Object[][] getContents() {
return data;
}
}
public class MyResource_zh_CN extends ListResourceBundle {
Object[][] data = new Object[][]{{"cancel", "取消"}};
@Override
protected Object[][] getContents() {
return data;
}
}
public class MyResource_en_US extends ListResourceBundle {
Object[][] data = new Object[][]{{"cancel", "cancel"}};
@Override
protected Object[][] getContents() {
return data;
}
}
2.测试
public class MyResourceTest {
public static void main(String[] args) {
// 没有Local.GERMAN对应的区域配置文件,会根据当前系统的区域设置(Local.CHINA)来加载配置文件,
// 由于没有Resource_zh_CN的配置文件,所以会加载默认的配置文件MyResource
// MyResource里 cancel = 取消default
ResourceBundle bundle = ResourceBundle.getBundle("MyResource", Locale.GERMAN);
String cancel = bundle.getString("cancel");
System.out.println(cancel);
// 增加 Resource_zh_CN的配置,再次运行,发现输出内容为Resource_zh_CN里的内容 cancel = 取消
}
}
PropertyResourceBundle
PropertyResourceBundle是ResourceBundle的一个子类。
当我们通过.properties文件定义资源时,ResourceBundle.getBundle()创建的就是PropertyResourceBundle实例,来加载Properties文件获取属性值的。
Properties
Properties类表示一组持久的属性。属性可以保存到流中,也可以从流中加载。
属性列表中的每个键及其对应的值都是一个字符串。
案例
加载resource目录下的my.properties文件,读取文件中的属性
public class PropertiesTest {
public static void main(String[] args) throws IOException {
// 加载资源文件
Properties properties = new Properties();
InputStream stream = PropertiesTest.class.getClassLoader().getResourceAsStream("my.properties");
properties.load(stream);
System.out.println(properties);
// getProperty(key)方法如果没有找到属性key,则返回null
String cancel = properties.getProperty("key");
System.out.println(cancel);
// getProperty(key,defaultValue)如果没有找到属性key,则返回defaultValue
String property = properties.getProperty("key", "value");
System.out.println(property);
// 获取所有属性名
Enumeration<?> propertyNames = properties.propertyNames();
while (propertyNames.hasMoreElements()) {
Object key = propertyNames.nextElement();
System.out.println("属性名:" + key);
}
Set<String> strings = properties.stringPropertyNames();
for (String keyName : strings) {
System.out.println("属性名:" + keyName);
}
// 打印属性和属性值,通常用于调试
PrintStream printStream = System.out;
properties.list(printStream);
}
}