资源障碍指南
最后修改:5月12日2019年5月12日
1.概述
许多软件开发人员在职业生涯中,面临开发多语言系统或应用程序的机会。这些通常用于来自不同地区或不同语言区域的最终用户。
维护和扩展这些应用始终挑战。同时使用各种本地化特定数据操作的能力通常是至关重要的。应用程序数据的修改应尽可能简单,无需重新编译。这就是我们通常避免硬编码标签或按钮名称的原因。
幸运的是,我们可以在向java上银行为我们提供这一课程,这有助于我们解决上述所有问题。
简单地说,ResourceBundle.使我们的应用程序能够从包含特定于语言环境的不同文件中加载数据。
1.1。资源捆绑
我们应该知道的第一件事是所有文件一个资源包必须位于同一软件包/目录中并具有常见的基本名称。它们可能具有指示由下划线符号分隔的语言,国家/地区或平台的语言设计的后缀。
如果有语言代码或存在语言和国家/地区代码,我们可以将国家代码附加国家代码很重要。
让我们来看看示例文件名:
- ExamplEsource.
- exampleresource_en.
- exampleresource_en_US.
- exampleresource_en_Un_Unix.
每个数据包的默认文件始终是一个没有任何后缀的文件 -ExamplEsource.。因为有两个子类ResourceBundle.:PropertyresourceBundle.和listresourcebundle.,我们可以互换地将数据保留在属性文件中以及Java文件中。
每个文件必须具有特定于区域设置的名称和一个适当的文件扩展名, 例如,exampleresource_en_US.Properties.或者example_en.java.。
1.2。属性文件 -PropertyresourceBundle.
属性文件由PropertyresourceBundle。它们以区分敏感的键值对的形式存储数据。
让我们分析示例属性文件:
#按钮继续禁止继续取消禁止=取消!Labels Hellolabel:你好
我们可以看到,有三种不同的样式定义键值对。
所有这些都是等同的,但第一个可能是最受欢迎的java.程序员。值得知道我们也可以在财产文件中提出评论。评论总是从#或者!!。
1.3。Java文件 -listresourcebundle.
首先,为了存储我们的语言特定数据,我们需要创建一个扩展的类listresourcebundle.并覆盖GetContents()方法。类名约定与属性文件相同。
对于每一个人区域设置,我们需要创建单独的Java类。
这是一个示例类:
公共类示例源_pl_pl扩展listResourceBundle {@Override受保护对象[] [] getContents(){return new对象[] [] {{rence“,”波兰Zloty“},{”tousdrate“,new bigdecimal(”3.401“)},{“城市”,新字符串[] {“华沙”,“克拉科夫”}}};}}
Java文件与属性文件有一个主要优势,这是持有我们想要的任何对象的可能性 - 不仅是字符串。
另一方面,每个修改或引入新的语言环境特定的Java类需要重新编译应用程序,而在没有任何额外努力的情况下可以扩展属性文件。
2.使用资源包
我们已经知道如何定义资源包,因此我们已准备好使用它。
让我们考虑短代码片段:
locale locale =新区域设置(“pl”,“pl”);ResourceBundle exampleBundle = ResourceBundle.GetBundle(“package.exampleresource”,locale);assertequals(examplebundle.getstring(“货币”),“波兰Zloty”);assertequals(examplebundle.getObject(“兴板”),新的BigDecimal(“3.401”));assertarrayequals(examplebundle.getstringarray(“城市”),新字符串[] {“华沙”,“克拉科夫”});
首先,我们可以定义我们的地区,除非我们不想使用默认值。
之后,让我们称之为静态工厂方法ResourceBundle.。我们需要通过包含包/目录的捆绑名称和区域设置为参数。
还有一个工厂方法,如果默认语言环境很好,那么只需要捆绑名称。一旦我们拥有对象,我们就可以通过键检索值。
此外,示例显示我们可以使用getString(字符串键)那getObject(字符串键),和getStringArray(String键)获得我们想要的价值观。
3.选择合适的捆绑资源
如果我们想使用捆绑资源,那么了解如何是很重要的java.选择捆绑文件。
让我们想象我们与一个需要在波兰语中需要标签的应用程序,但是您的默认值JVM.当地人是locale.us.。
在开始,应用程序将查找类路径中的文件,适用于您要求的区域设置。它从最具体的名称开始,即一个包含平台,一个国家和语言的名称。
然后,它进入更一般。如果没有匹配,则会返回到此时没有平台的默认区域设置。
如果没有匹配,它将尝试读取默认包。当我们查看所选文件名的顺序时,一切都应该清楚:
- label_pl_pl_unix.
- label_pl_pl.
- label_pl.
- label_en_us.
- label_en.
- 标签
我们应该记住,每个名称都代表.java.和。特性文件,但前者优先于后者优先考虑。什么时候没有合适的文件,aMissingResourceException.被抛出。
4.继承
资源束概念的另一个优点是属性继承。这意味着包含在较少特定文件中的密钥值对由继承树中更高的文件继承。
让我们假设我们有三个属性文件:
#ource.properties cancelButton =取消#resource_pl.properties continuebutton = dalej #ource_pl_pl.properties backbutton = cofnij
Resource Bundle检索区域设置(“PL”,“PL”)将返回结果中的所有三个键/值。值得一提,返回默认的区域设置捆绑包只要考虑财产继承。
更,ListResourceBundles.和PropertyResourceBundles.不在相同的层次结构中。
因此,如果在类路径中找到属性文件,则只能从属性文件继承键值对。相同的规则适用于Java文件。
5.定制
我们上面学到的只是关于默认实施金宝搏官网188beResourceBundle.。但是,我们可以改变其行为的方法。
我们通过扩展来实现这一目标ResourceBoundle.Control.Control.并覆盖其方法。
例如,我们可以更改缓存中保持值的时间,或者在应重新加载缓存时确定条件。
为了更好地理解,让我们准备一个简短的方法作为一个例子:
公共类exampleControl扩展ResourceBundle.Control {@Override公共列表 getCandidateLocales(String s,locale locale){return arrays.aslist(新区域设置(“pl”,“pl”));}}
此方法的目的是改变在类路径中选择文件的方式。我们可以看到,exampleControl.将只返回波兰语地区,无论默认或定义是什么地区是。
6. UTF-8
因为仍有许多应用程序使用JDK 8.或旧版本,值得了解这一点先于java.9.ListResourceBundles.还有一个优势PropertyResourceBundles.。由于Java文件可以存储字符串对象,它们能够按住任何支持的字符UTF-16.编码。
相反,PropertyresourceBundle.默认使用默认加载文件ISO 8859.1.编码,字符较少UTF-8.(导致我们的波兰语示例的问题)。
为了保存超出的字符UTF-8.,我们可以使用原生到ASCII转换器 -天然2 SASCII.。它通过编码它们来转换不符合ISO 8859-1的所有字符\ uxxxx.符号。
这是一个示例命令:
native2ascii -encoding utf-8 utf8.properties nontf8.properties
让我们看看在更改编码之前和之后的属性如何?
#before polishhello =cześć#After Polishhello = CZE \ U015B \ U0107
幸运的是,java 9不再存在这种不便。JVM.读取属性文件UTF-8.编码,使用非拉丁字符没有问题。
7.结论
Bundleresource.包含大部分我们需要开发多语言应用程序的内容。我们所覆盖的功能使不同的定位人员非常直截了当地。
我们还避免了硬编码值,允许我们扩展支持地狱通过简单地添加新的地区文件允许我们的应用程序顺利修改和维护。
一如既往,示例代码可用在github上。