`
xwood
  • 浏览: 102107 次
  • 性别: 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编写

    本篇将深入探讨Java中实现国际化的必备工具以及相关的编码转换问题。 一、Java中的国际化 1. **资源绑定文件(Properties文件)** 在Java中,我们通常使用`.properties`文件来存储不同语言的文本资源。例如,`...

    java国际化实现框架底层源码

    Java国际化实现框架底层源码分析 Java国际化(i18n,Internationalization)是为了支持不同地区的语言和文化差异,提供了一种灵活的方式来管理和显示应用程序的文本、日期、数字和其他文化敏感的信息。Java提供了...

    Java 程序国际化教程+源码

    Java程序国际化还包括日期和时间的格式化,这可以通过`java.time.format.DateTimeFormatter`类实现。例如: ```java DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", new ...

    Java 国际化操作

    2. **Resource Bundle**:资源包是Java国际化的关键组成部分,它是一个包含特定语言环境下的文本和数据的文件集合。通常以.properties格式存储,例如`messages_en.properties`和`messages_fr.properties`分别代表...

    JAVA国际化

    Java国际化(i18n,Internationalization)是Java平台提供的一种机制,用于支持应用程序在全球不同地区的本地化。这个过程涉及到将应用的文本、日期、数字格式等与特定文化或地区相关的元素分离,以便在不同语言环境...

    java 国际化转换

    ### Java国际化转换详解 #### 一、Java国际化概念与意义 在软件开发过程中,随着产品的全球化,越来越多的应用程序需要支持多种语言环境。这就引出了一个重要的概念——国际化(Internationalization)。通常简称...

    Java internationalization basics.zip_JAVA 国际化_doc_国际化 java

    Java国际化的概念主要涉及到软件在全球范围内适应不同语言和文化环境的能力。在Java中,这个过程称为i18n(国际化)和l10n(本地化)。i18n是"internationalization"的首字母缩写,而l10n是"localization"的首字母...

    Java中的国际化日期和时间格式实现:策略与实践

    本文将详细介绍如何在Java中实现国际化的日期和时间格式,包括国际化的基本概念、Java中的相关类和方法、以及实际应用案例。 国际化的日期和时间格式是开发全球应用程序时必须考虑的重要方面。Java提供了丰富的API来...

    java 国际化说明

    Java国际化通过`Locale`、`ResourceBundle`和`MessageFormat`等类提供了强大的多语言支持能力。开发人员可以根据用户所在的地理位置和语言环境,动态加载和显示相应的资源文件,从而提升用户体验,使应用程序能够更...

    java数据格式化

    ### 一、Java数据格式化相关类介绍 #### 1. `java.text`包 `java.text`包提供了用于文本、日期和数值格式化的一系列类。这些类设计得与特定语言无关,使得Java程序能够以国际化的方式处理和显示数据。 ##### 1.1 ...

    Java国际化

    Java国际化,也称为I18N(Internationalization的缩写,因为去掉首尾字母后有18个字母),是Java平台提供的一种强大的功能,旨在帮助开发者创建能够适应不同语言、地区和文化背景的软件应用。Java国际化允许程序在不...

    java国际化 调用google apl

    "src"目录存放源代码,其中可能有一个或多个Java类用于与Google翻译API交互,以及处理国际化相关的逻辑。 "build"目录通常是构建过程中临时文件的存储位置,包括编译后的类文件和其他中间产物。 "lib"目录可能包含...

    不错的java图形化例子

    Java图形化界面(GUI,Graphical ...随着章节的深入,可能还会涉及更复杂的话题,如对话框、菜单、拖放功能、国际化、自定义组件等。总之,这个“不错的java图形化例子”是一个全面了解和掌握Java GUI编程的宝贵资源。

    JAVA Web實現國際化插件

    综上所述,"JAVA Web实现国际化插件"是一个实用的工具,可以帮助开发者轻松地处理Java Web应用的国际化需求,通过`ResourceBundle`和相关编辑工具,使得本地化工作更加高效和规范。开发者可以通过学习PPT详解和实际...

    java 国际象棋棋盘

    总结来说,创建Java国际象棋棋盘项目涉及到以下几个关键知识点: 1. 类和对象:使用面向对象编程设计棋盘、棋子和游戏引擎。 2. 二维数组:用二维数组表示棋盘结构。 3. 循环和条件语句:用于初始化棋盘和打印棋盘...

    java操作时间工具类

    但是,由于这个类的设计并不完美,存在线程安全问题以及不支持国际化等问题,所以在Java 8之后,已经不再推荐使用。 2. `java.text.SimpleDateFormat`:这是一个具体的日期时间格式化类,用于将日期或时间格式化为...

    struts1.2 国际化

    Java 语言本身对国际化提供了强大的支持,主要通过 `java.util.Locale`、`java.util.ResourceBundle` 和 `java.text.MessageFormat` 这三个关键类实现。 ##### 1. Locale 类 - **核心功能**:`Locale` 类是 Java ...

    JAVA发送邮件实现,消息格式化

    `MessageFormat`是Java国际化(i18n)支持的一部分,它可以将变量替换为指定的值,使得输出的消息具有可读性和一致性。例如,假设我们有一个模板字符串`"欢迎,{0}!"`,我们可以使用`MessageFormat.format()`方法将...

    java国际化

    Java 国际化(i18n)是Java平台提供的一种强大的功能,它允许软件根据用户的地域和语言偏好来展示适应性的内容。这个过程涉及到资源的本地化和全球化,使得程序能够灵活地处理多种语言环境。在Java中,主要通过`java...

Global site tag (gtag.js) - Google Analytics