`
xwood
  • 浏览: 100618 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Java国际化相关类介绍

阅读更多
    在Web系统的国际化问题中我们常提到本地化(Locale)显示,这里的本地化通常包括数字(NumberFormat),货币(NumberFormat.getCurrencyInstance()),时间(DateFormat)及任意文本(MessageFormat)本地化。下面,就对这几个类的大致用法做一个概括性的描述,需要更加详细的用法可以参考一个API,基本上都还是比较好理解的。

【Locale】
构造参数:
1.Language.常用的有zh, en, de...
2.Country.常用的有CN, TW, US, GB(Great Britain)...
3.Variant.这个似乎只是起一个标识(供应商或浏览器)的作用,这里贴上API上的说明:vendor and browser specific code
    Locale在VM加载的时候就已经初始化了默认值,所以我们可以通过Locale.getDefault()方法获取默认的Locale实例。当然也可以根据上面的三个参数手动创造新的Locale实例,如new Locale(Language, Country, Variant),示例如下:
Locale locale1 = Locale.getDefault();
		System.out.println("locale default display name: " + locale1.getDisplayName());
		System.out.println("locale default display language: " + locale1.getDisplayLanguage());
		System.out.println("locale default display country: " + locale1.getDisplayCountry());
		System.out.println("locale default display variant: " + locale1.getDisplayVariant());
		
		Locale locale2 = Locale.getDefault(Locale.Category.FORMAT);
		System.out.println("locale default display name: " + locale2.getDisplayName());
		System.out.println("locale default display language: " + locale2.getDisplayLanguage());
		System.out.println("locale default display country: " + locale2.getDisplayCountry());
		System.out.println("locale default display variant: " + locale2.getDisplayVariant());
		
		Locale locale3 = Locale.getDefault(Locale.Category.FORMAT);
		System.out.println("locale default display name: " + locale3.getDisplayName());
		System.out.println("locale default display language: " + locale3.getDisplayLanguage());
		System.out.println("locale default display country: " + locale3.getDisplayCountry());
		System.out.println("locale default display variant: " + locale3.getDisplayVariant());
		
		Locale locale4 = new Locale("en", "GB");
		System.out.println("locale default display name: " + locale4.getDisplayName());
		System.out.println("locale default display language: " + locale4.getDisplayLanguage());
		System.out.println("locale default display country: " + locale4.getDisplayCountry());
		System.out.println("locale default display variant: " + locale4.getDisplayVariant());


    在Java.text包下面的格式化类中,基本上每一个格式化都会与具体的Locale相关,也就是进行特定语境下的Format。所以,通常在构造一个Format实体的时候,我们通常会传递一个Locale实体作为参数。

【NumberFormat】
    NumberFormat可以对所有的Number进行Format,而针对特殊的Decimal,Java专门创建了一个DecimalFormat予以处理。在处理Decimal的时候需要考虑小数位的取舍位数,数字分隔符等问题,而使用类似“#,##0.0#”的格式化字符串可以一次解决多个问题,是比较推荐的使用方法。示例如下:
class NumberFormatTest {
	
	private Locale loc;
	
	public NumberFormatTest(Locale loc){
		this.loc = loc;
	}
	
	public void numberTest(){
		NumberFormat mft = NumberFormat.getNumberInstance(loc);
		double amt = 123123123.12312;
		System.out.println(mft.format(amt));
		System.out.println(mft.format(amt, new StringBuffer("&&"), new FieldPosition(13213123)).toString());
	}

	public void currencyTest(){
		NumberFormat mft = NumberFormat.getCurrencyInstance(loc);
		double amt = 123123123.12312;
		System.out.println(mft.format(amt));
		System.out.println(mft.format(amt, new StringBuffer("&&"), new FieldPosition(-1)).toString());
	}
	
	public void percentTest(){
		NumberFormat mft = NumberFormat.getPercentInstance(loc);
		double amt = 123123123.12312;
		System.out.println(mft.format(amt));
		System.out.println(mft.format(amt, new StringBuffer("&&"), new FieldPosition(-1)).toString());
	}
	
	public void decimalTest(){
		/*
		 * If you supply a pattern with multiple grouping characters, 
		 * the interval between the last one and the end of the integer is the one that is used
		 * 分隔间距的大小依据最后一组分组的长度确定,在有小数点时是指在小数点前的一组
		 */
		DecimalFormat dft1 = new DecimalFormat("#,##");
		System.out.println(dft1.format(111111.11));
		System.out.println(dft1.format(.11));
		System.out.println(dft1.format(111111));
		
		/*
		 * #和0都指代数字,只不过0在该位置上没有数据的时候以0代替,而#则直接忽略不显示
		 */
		DecimalFormat dft2 = new DecimalFormat("#,##0.0#");
		System.out.println(dft2.format(111111.11));
		System.out.println(dft2.format(.11));
		System.out.println(dft2.format(111111));
		
		
	}
	
	
	public static void main(String[] args){
		Locale loc = new Locale("en", "US");
		NumberFormatTest test = new NumberFormatTest(loc);
		test.decimalTest();
	}
}

【DateFormat】
    DateFormat是我们比较常用的一种格式化方法,除了使用DateFormat之外,对于页面显示,我个人更加喜欢SimpleDateFormat,这个类可以更加人性化地显示日常所需。示例如下:
public class DateTimeTest {

	private Locale loc;
	
	public DateTimeTest(Locale loc){
		this.loc = loc;
	}
	
	public void dateTest(){
		DateFormat dft = DateFormat.getDateInstance(DateFormat.FULL, loc);
		System.out.println(dft.format(new Date()));
		SimpleDateFormat smft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S", loc);
		System.out.println(smft.format(new Date()));
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		DateTimeTest test = new DateTimeTest(Locale.getDefault());
		test.dateTest();
	}

}

【MessageFormat】
    MessageFormat在国际化显示Message时经常用到,其最大的特点就是对于消息的定制显示,所谓定制也就是模版化,即每个消息在显示之前都需要定制其显示模版,在显示的时候只需要填充需要的变量便可以达到动态显示的目的了;另外,除了动态显示之外,这个类还可以根据字符串与字符串模版解析出之前传递进来的参数数组,但其解析存在很大的不确定性,目前,个人还没找到其卓越贡献之处。示例如下:
public class MessageTest {

	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String pattern = "On {2,date,long}, a {0} destroyed {1} houses and caused {3,number,currency} of damage.";
		MessageFormat mft = new MessageFormat(pattern, Locale.getDefault());
		String msg = mft.format(new Object[]{
			"hurricane",
			99,
			new Date(),
			100000000
		});
		System.out.println(msg);
		
		
		/*
		 * parse with its type
		 */
		Object[] objs;
		try {
			 objs = mft.parse(msg);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		
		if(objs != null){
			for(int i = 0; i < objs.length; i++){
				System.out.print(objs[i].getClass() + " : ");
				System.out.println(objs[i]);
			}
		}
		
		/*
		 * When a single argument is parsed more than once in the string, 
		 * the last match will be the final result of the parsing
		 */
		MessageFormat mf = new MessageFormat("{0,number,#.##}, {0,number,#.#}");
		Object[] objs1 = {new Double(3.1415)};
		String result = mf.format( objs1 );
		// result now equals "3.14, 3.1"
		System.out.println(result);
		objs1 = null;
		objs1 = mf.parse(result, new ParsePosition(0));
		// objs now equals {new Double(3.1)}
		for(int i = 0; i < objs1.length; i++){
			System.out.println(objs1[i]);
		}

		MessageFormat mf2 = new MessageFormat("{0}, {0}, {0}");
		String forParsing = "x, y, z";
		Object[] objs2 = mf2.parse(forParsing, new ParsePosition(0));
		// result now equals {new String("z")}
		for(int i = 0; i < objs2.length; i++){
			System.out.println(objs2[i]);
		}
	}

}


    很明显,我们不会在代码里显示的调用判断语句去决定调用什么格式化显示,这样的代码显得非常不雅观,而且没有扩展性、可维护性,所以我们通常都根据Locale类自动决定页面的显示,这里涉及到另一个概念:Resource Bundle。

【Resource Bundle】
    要构成Bundle,自然需要一堆Properties文件。那么VM又是如何让这些Bundle文件有序工作的呢,根据Core Java的说明可知,getBundle方法会加载文件会涉及到以下几个Properties文件:
引用
1.bundleName_currentLocaleLanguage_currentLocaleCountry_currentLocaleVariant
2.bundleName_currentLocaleLanguage_currentLocaleCountry
3.bundleName_currentLocaleLanguage
4.bundleName_defaultLocaleLanguage_defaultLocaleCountry_defaultLocaleVariant
5.bundleName_defaultLocaleLanguage_defaultLocaleCountry
6.bundleName_defaultLocaleLanguage
7.bundleName

    每次,getBundle方法加载Properties文件时,首先会根据Locale加载符合BundleName_Language_Country_Variant命名规范的文件,然后还会依次加载符合BundleName_Language_Country,BundleName_Language,BundleName命名规范的文件,如果在加载过程中没有加载到相关文件,则会将Locale转换成Default Locale再加载一次。并最终将这些Properties文件组合成一个Bundle,形成一定的继承关系。其中,BundleName_Language_Country_Variant为最子一级,BundleName为最父一级,在getString或getObject查询相关内容时,则从最子级开始,往最父级查询,直到找到相关内容。
    在使用Bundle进行国际化处理时,需要注意Properties文件需要转成通用的UTF-8格式,以达到通用的转码目的。这样,如果使用eclipse编辑国际化资源文件,则可以直接使用PropertiesEditor插件。
示例代码如下:
public class ResourceTest {

	/**
	 * @param args
	 * @throws UnsupportedEncodingException 
	 */
	public static void main(String[] args) throws UnsupportedEncodingException {
		//注意中文的资源文件需要先进行native2ascii的转码,使其成为ascii码才能识别
		Locale loc = new Locale("zh", "CN");
		//getBundle方法默认使用ResourceTest.ClassLoader加载资源,默认路径为classes根目录
		ResourceBundle bundle = ResourceBundle.getBundle("text/internationalization/resource/test", loc);
		String name = bundle.getString("name");
		System.out.println(name);
		//常用的转码方式,以ISO_8859_1为中介转为需要的编码,也就是都需要先变成二进制的编码,因为所有编码都是对二进制进行组合识别
		//System.out.println(new String(name.getBytes("ISO_8859_1"), "UTF-8"));
	}

}

资源文件命名:
引用

test_en_US.properties
test_zh_CN.properties



分享到:
评论

相关推荐

    java常用工具类的使用

    而Date的其他构造方法和普通方法的API都不容易实现国际化,因此目前Date类的大多数方法都被标识为过时,表示更灵活的时间类请参考java.util.Calendar。 Date的输出结果是按照国际通用格式输出的,而中国更习惯于...

    JAVA_API1.6文档(中文)

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    Java 1.6 API 中文 New

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类。...

    java api最新7.0

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类。...

    JavaAPI1.6中文chm文档 part1

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    疯狂JAVA讲义

    9.6.1 Java国际化的思路 346 9.6.2 Java支持的语言和国家 346 9.6.3 完成程序国际化 347 9.6.4 使用MessageFormat处理包含占位符的字符串 349 9.6.5 使用类文件代替资源文件 350 9.6.6 使用NumberFormat格式化...

    JAVA核心技术第八版(上下卷)全部源码

    全面覆盖Java技术的高级主题,包括流与文件、XML、网络、数据库编程、高级Swing、高级 AWT、JavaBean构件、安全、分布式对象、脚本、编译与注解处理等,同时涉及本地化、国际化以及Java SE 6的内容。《JAVA核心技术...

    java jdk-api-1.6 中文 chmd

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    JavaAPI中文chm文档 part2

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    Java的ppt课件

    通常用在国际化/本地化程序中与地区/语言相关的方式显示日期、数字或文本信息。 主要方法: public Locale(String language) public Locale(String language,String country) public static Locale getDefault() ...

    精通Java:JDK、数据库系统开发Web开发(实例代码)

    第19章 国际化和本地化 第20章 泛型程序设计 第21章 访问数据库 第22章 获取XML数据 第23章 处理电子邮件 第24章 JSP技术应用 第5篇 综合案例 第25章 汉诺塔游戏 第26章 学生成绩查询系统 第27章 网上用户注册系统...

    JAVA面试题最全集

    60.JAVA语言国际化应用,Locale类,Unicode 61.描述反射机制的作用 62.如何读写一个文件? 63.在图形界面中,一个按钮如何处理鼠标点击事件? 64.在图形界面中,一个表格,如何实现编辑单元格时弹出下拉框? ...

    java 面试题 总结

    JAVA相关基础知识 1、面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用...

    java面试宝典

    148、如何实现JSP的国际化? 36 150、如何在JSP中包括绝对路径文件? 使用URLConnection即可。 37 151、在servlets和JSP之间能共享session对象吗? 37 152、如何设置cookie在某一时间后过期? 37 153、如何获得当前...

    JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载地址

    AVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载 ...包括了用于产品环境的各种库类,以及给开发员使用的补充库,如国际化的库、IDL库。 JDK中还包括各种例子程序,用以展示Java API中的各部分。

    [Java参考文档]

    java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类...

    JAVA帮助文档全系列_JDK1.5_、JDK1.6、_JDK1.7_官方中英完整版下载

    各个版本的JDK下载地址 JAVA帮助文档全系列 JDK1.5 JDK...包括了用于产品环境的各种库类,以及给开发员使用的补充库,如国际化的库、IDL库。 JDK中还包括各种例子程序,用以展示Java API中的各部分。 JDK 官方下载

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    第10章 准备环球旅行——应用程序国际化 243 10.1 讲解 244 10.1.1 概念介绍 244 10.1.2 设置Locale 249 10.1.3 隔离语言环境相关数据 252 10.1.4 格式化 258 10.2 练习 266 10.2.1 对单独的文件进行国际化 ...

    java 实效编程百例 pdf + 源代码

    本书通过100多个精选的实例讲解了利用Java进行应用程序开发的各个方面,涵盖了控件、界面、多媒体控制、图像处理、操作系统、磁盘文件、数据库、网络应用、邮件和通信、Java Beans、国际化和本地化等方面的内容。...

Global site tag (gtag.js) - Google Analytics