Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
如果你查看国际化的源代码,你会发现硬编码的英文消息已被移除。由于消息不再是硬编码的,并且因为语言代码是在运行时指定的,因此可以在全球范围内分发相同的可执行文件。本地化不需要重新编译。该程序已国际化。
你可能想知道消息的文本发生了什么,或者语言和国家代码是什么意思。别担心。当你逐步完成示例程序的国际化过程时,你将了解这些概念。
属性文件存储有关程序或环境特征的信息。属性文件是纯文本格式。你可以使用几乎任何文本编辑器创建该文件。
在示例中,属性文件存储要显示的消息的可翻译文本。在程序国际化之前,该文本的英文版本在 System.out.println
语句中进行了硬编码。默认属性文件,名为 MessagesBundle.properties
,包含以下行:
greetings = Hello farewell = Goodbye inquiry = How are you?
现在消息在属性文件中,它们可以被翻译成各种语言。不需要更改源代码。法语翻译人员创建了一个名为 MessagesBundle_fr_FR.properties
的属性文件,其中包含以下行:
greetings = Bonjour. farewell = Au revoir. inquiry = Comment allez-vous?
请注意,等号右侧的值已被翻译,但左侧的键未更改。这些键不能更改,因为它们将在你的程序获取翻译文本时被引用。
属性文件的名称很重要。例如,MessagesBundle_fr_FR.properties
文件的名称包含 fr
语言代码和 FR
国家/地区代码。创建 Locale
对象时也会使用这些代码。
Locale
对象标识特定语言和国家/地区。以下语句定义了 Locale
,其语言为英语,国家/地区为美国:
aLocale = new Locale("en","US");
下一个示例为加拿大和法国的法语创建 Locale
对象:
caLocale = new Locale("fr","CA"); frLocale = new Locale("fr","FR");
该程序非常灵活。该程序不是使用硬编码语言和国家/地区代码,而是在运行时从命令行获取它们:
String language = new String(args[0]); String country = new String(args[1]); currentLocale = new Locale(language, country);
Locale
对象只是标识符。定义 Locale
后,将其传递给执行有用任务的其他对象,例如格式化日期和数字。这些对象是 locale-sensitive (语言环境敏感的),因为它们的行为根据 Locale
而变化。ResourceBundle
是语言环境敏感对象的示例。
ResourceBundle
对象包含特定于语言环境的对象。你使用 ResourceBundle
对象来隔离语言环境敏感数据,例如可翻译文本。在示例程序中,ResourceBundle
由包含我们要显示的消息文本的属性文件支持。
ResourceBundle
创建如下:
messages = ResourceBundle.getBundle("MessagesBundle", currentLocale);
传递给 getBundle
方法的参数标识将访问哪些属性文件。第一个参数 MessagesBundle
引用此属性文件系列:
MessagesBundle_en_US.properties MessagesBundle_fr_FR.properties MessagesBundle_de_DE.properties
Locale
是 getBundle
的第二个参数,指定选择哪个 MessagesBundle
文件。创建 Locale
后,语言代码和国家/地区代码将传递给其构造函数。请注意,在属性文件的名称中,语言和国家/地区代码跟在 MessagesBundle
之后。
现在,你只需从 ResourceBundle
获取已翻译的消息。
属性文件包含键值对。值包含程序将显示的已翻译文本。使用 getString
方法从 ResourceBundle
获取已翻译的消息时要指定键。例如,要获取由 greetings 键标识的消息,请按如下方式调用 getString
:
String msg1 = messages.getString("greetings");
示例程序使用键 greetings
,因为它反映了消息的内容,但它可能使用了另一个 String
,例如 s1
或 msg1
。只需记住,键在程序中是硬编码的,并且必须存在于属性文件中。如果你的翻译人员意外修改了属性文件中的键,getString
将无法找到这些消息。
就是这样。如你所见,国际化程序并不太难。它需要一些规划和一些额外的编码,但好处是巨大的。为了向你提供国际化过程的概述,本课程中的示例程序有意保持简单。在阅读下面的课程时,你将了解 Java 编程语言的更高级的国际化功能。