Java国际化ResourceBundle详解
在Java开发中,ResourceBundle是一种方便地管理本地化资源的机制。它可以使得程序能够根据当前系统环境的语言和国家/地区来自动加载相应的本地化资源文件,从而避免了硬编码和减少了重复的代码。以下是使用ResourceBundle的基本步骤:
1. 准备资源文件
ResourceBundle通过加载资源文件来实现本地化,因此需要为每种语言和国家/地区准备一个对应的资源文件。资源文件可以是.properties格式的文本文件,也可以是.class文件或.jar文件。
在资源文件中,需要为每个需要本地化的字符串指定一个属性名,然后为每个属性名分别提供该语言下的翻译。例如,以下是一个名为messages.properties的资源文件的示例:
greeting=Hello
farewell=Goodbye
在不同的语言和国家/地区下,可以为同一属性名提供不同的翻译。例如,以下是名为messages_fr.properties的法语资源文件的示例:
greeting=Bonjour
farewell=Au revoir
2. 加载资源文件
在Java中,可以使用ResourceBundle类来加载资源文件。ResourceBundle类提供了几种不同的构造函数来加载资源文件,例如:
ResourceBundle rb = ResourceBundle.getBundle("messages", Locale.getDefault());
这个语句会根据当前系统环境的默认语言和国家/地区来加载名为messages的资源文件。如果系统环境是英语和美国,那么这个语句会加载messages.properties资源文件。如果系统环境是法语和法国,那么这个语句会加载messages_fr.properties资源文件。
如果需要加载指定语言和国家/地区下的资源文件,可以使用带有Locale参数的getBundle()方法。例如:
Locale locale = new Locale("fr", "FR");
ResourceBundle rb = ResourceBundle.getBundle("messages", locale);
这个语句会加载名为messages_fr_FR.properties的法语/法国资源文件。
3. 获取本地化字符串
一旦成功加载了资源文件,就可以使用ResourceBundle的getString()方法来获取本地化字符串。例如:
String greeting = rb.getString("greeting");
String farewell = rb.getString("farewell");
这些语句会从资源文件中获取属性名为greeting和farewell的本地化字符串,并将它们分别赋值给greeting和farewell变量。如果无法找到指定的属性名,getString()方法会抛出MissingResourceException异常。
4. ResourceBundle 使用技巧
除了上述基本步骤,使用ResourceBundle还有以下一些值得注意的特点和技巧:
4.1 选择合适的资源文件格式
ResourceBundle支持多种资源文件格式,包括.properties、.xml和.class文件等。对于简单的本地化字符串,.properties格式通常是最常用的选择,因为它简单易用、易于编辑和本地化。
对于较复杂的本地化资源,如图像、声音、视频等,可能需要使用其他格式的资源文件。例如,可以使用.class文件或.jar文件来包含图像或声音文件,并使用ResourceBundle的ClassLoader.getSystemClassLoader()方法来加载这些文件。
4.2 处理本地化字符串中的特殊字符
在本地化字符串中可能包含各种特殊字符,如换行符、制表符、Unicode字符等。如果直接将这些字符嵌入到资源文件中,可能会导致不必要的麻烦和错误。
为了避免这些问题,可以使用Java的转义字符来表示这些特殊字符。例如,可以使用"\n"表示换行符,“\t"表示制表符,”\uXXXX"表示Unicode字符等。
4.3 处理缺失的本地化字符串
在某些情况下,可能存在某些语言下的本地化字符串没有提供翻译的情况。为了避免程序出现MissingResourceException异常,可以在资源文件中为这些缺失的字符串提供一个默认的翻译,如英语翻译。例如,以下是一个带有默认翻译的messages_fr.properties文件的示例:
greeting=Bonjour
farewell=Au revoir
warning=Attention: This message has no translation in French. Please refer to the English version.
这样,在法语环境下,如果无法找到某个属性名的本地化字符串,ResourceBundle就会自动返回该属性名的默认翻译,从而避免了程序出现异常。
4.4 处理动态本地化字符串
有些本地化字符串可能包含动态内容,如时间、日期、数字、货币等。为了正确地本地化这些字符串,需要使用Java的格式化机制,如MessageFormat和NumberFormat等。例如,以下是一个使用MessageFormat来本地化动态字符串的示例:
String pattern = rb.getString("greeting");
Object[] arguments = {"John"};
String greeting = MessageFormat.format(pattern, arguments);
这个示例中,pattern是一个包含占位符"{0}“的本地化字符串,”{0}“表示需要替换为动态内容的位置。arguments是一个包含实际动态内容的数组,它会按照顺序依次替换”{0}"的位置。最后,MessageFormat.format()方法会返回一个本地化后的字符串。
4.5 处理多个资源文件
在一些情况下,可能需要使用多个资源文件来管理不同类型或不同用途的本地化资源。在这种情况下,可以使用ResourceBundle.Control类的方法来指定资源文件的搜索路径和加载顺序。
例如,可以使用ResourceBundle.Control.getControl()方法来获取默认的ResourceBundle.Control实例,然后使用ResourceBundle.getBundle()方法来指定基础名称和Locale信息,以便查找合适的资源文件。例如,以下是一个使用多个资源文件来管理本地化字符串的示例:
ResourceBundle.Control control = ResourceBundle.Control.getControl(ResourceBundle.Control.FORMAT_PROPERTIES);
ResourceBundle messages = ResourceBundle.getBundle("Messages", new Locale("fr"), control);
ResourceBundle errors = ResourceBundle.getBundle("Errors", new Locale("fr"), control);String greeting = messages.getString("greeting");
String error = errors.getString("invalid_input");System.out.println(greeting); // Bonjour
System.out.println(error); // Entrée invalide
在这个示例中,我们使用ResourceBundle.Control.FORMAT_PROPERTIES指定了资源文件的格式为.properties文件,然后分别使用Messages和Errors作为基础名称来获取不同类型的资源文件。这样,我们就可以轻松地管理不同类型的本地化资源,从而使程序更加可读和易于维护。
4.6 自定义资源加载器
如果默认的资源加载机制无法满足需求,我们还可以自定义资源加载器来实现更高级的功能。自定义资源加载器需要继承java.util.ResourceBundle.Control类,并重写其中的方法来实现自定义逻辑。
例如,以下是一个使用自定义资源加载器来加载本地化字符串的示例:
public class MyResourceLoader extends ResourceBundle.Control {@Overridepublic ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)throws IllegalAccessException, InstantiationException, IOException {String bundleName = toBundleName(baseName, locale);String resourceName = toResourceName(bundleName, "myproperties");InputStream stream = loader.getResourceAsStream(resourceName);if (stream != null) {try {return new PropertyResourceBundle(stream);} finally {stream.close();}} else {return super.newBundle(baseName, locale, format, loader, reload);}}
}ResourceBundle.Control control = new MyResourceLoader();
ResourceBundle messages = ResourceBundle.getBundle("Messages", new Locale("fr"), control);String greeting = messages.getString("greeting");System.out.println(greeting); // Bonjour
在这个示例中,我们定义了一个名为MyResourceLoader的自定义资源加载器,并重写了其中的newBundle()方法来实现自定义资源加载逻辑。然后,我们使用这个自定义资源加载器来获取Messages资源文件中的本地化字符串。这样,我们就可以实现更高级的资源加载功能,从而满足更复杂的需求。
4.7 动态更新资源文件
有时候,在应用程序运行期间,可能需要动态地更新资源文件中的某些值。在Java中,我们可以使用PropertyResourceBundle类来实现这个功能。
PropertyResourceBundle是ResourceBundle的一个子类,它可以读取.properties格式的资源文件,并将其转换为一个键值对的形式。然后,我们可以通过这个键值对来动态地更新资源文件中的值。
例如,以下是一个使用PropertyResourceBundle来动态更新本地化字符串的示例:
// 加载资源文件
InputStream stream = new FileInputStream("Messages.properties");
PropertyResourceBundle bundle = new PropertyResourceBundle(stream);// 动态更新本地化字符串
bundle.handleKey("greeting", (key, value) -> "Hello");// 输出本地化字符串
String greeting = bundle.getString("greeting");
System.out.println(greeting); // Hello
在这个示例中,我们首先使用FileInputStream来加载Messages.properties资源文件,然后将其转换为一个PropertyResourceBundle对象。然后,我们使用handleKey()方法来动态地更新greeting这个键对应的值。最后,我们使用getString()方法来获取更新后的本地化字符串。
这种动态更新资源文件的方式可以使应用程序更加灵活,能够快速响应变化。但是需要注意的是,这种方式需要保证资源文件的正确性和一致性,否则可能会导致应用程序运行出错。
5. 总结
Java中的ResourceBundle提供了一种便捷的方式来管理本地化资源,使得应用程序能够轻松地适应不同的语言和文化环境。通过熟练掌握ResourceBundle的使用方法,我们可以在开发Java应用程序时更加灵活和高效。
相关文章:
Java国际化ResourceBundle详解
在Java开发中,ResourceBundle是一种方便地管理本地化资源的机制。它可以使得程序能够根据当前系统环境的语言和国家/地区来自动加载相应的本地化资源文件,从而避免了硬编码和减少了重复的代码。以下是使用ResourceBundle的基本步骤: 1. 准备…...
一文高端Android性能优化-总结篇
以下从几个方面来总结一下Android的性能优化:1:界面卡顿优化2:内存优化3:App启动优化界面卡顿优化Android的界面为每秒60帧,即必须在16ms内完成1帧的绘制,如果某个方法耗时过程,导致16ms内无法完…...
深入讲解CFS组调度!(上)
注:本文缩写说明 一、CFS组调度简介 1.1. 存在的原因 总结来说是希望不同分组的任务在高负载下能分配可控比例的CPU资源。为什么会有这个需求呢,比如多用户计算机系统每个用户的所有任务划分到一个分组中,A用户90个相同任务,而B…...
大数据实操项目分享:餐饮智能推荐服务在线实习项目
项目背景:在“互联网"背景下,餐饮企业的经营方式发生了很大的变革:团购和020拓宽了销售 渠道,电子点餐、店内WIFI等信息技术提升了服务水平,大数据、私人定制更好地满足了细分市场的需求等。但是与此同时…...
代码随想录day38
动态规划五部曲 确定dp数组以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 509. 斐波那契数 https://leetcode.cn/problems/fibonacci-number/ class Solution {public int fib(int n) {if(n0) return 0;if(n<3) return 1;int[] dp new int[n]…...
《计算机网络:自顶向下方法》实验5:TCP
Q1 包含HTTP POST消息的TCP报文段的序号是多少?注意:为了发现POST 命令, 你需要在wireshark底部的报文内容域窗口中去查找,查找数据中包含 “POST”的段。 如图所示,由报文中的POST 和 HTTP/1.1可知,其包含HTTP POST消息; TCP报文段的序号可见TCP报文: Sequence Number:…...
【踩坑指南】Stable Diffusion 服务器端部署笔记
文章目录下载github文件配置环境ckpt文件权重下载生成图像NSFW检查(瑟图过滤)下载github文件 https://github.com/CompVis/stable-diffusion 这个网址,下载压缩包解压,也可以用git clone下载 配置环境 这一步坑最多,…...
[qiankun]-多页签缓存
[qiankun]-多页签缓存环境功能需求多页签缓存方案方案1.主服务进行html替换方案2.微服务vnode 替换方案3.每个微服务都不卸载微服务加载方式的选择微服务的路由路径选择微服务的缓存工具微服务的容器使用tab作为微服务的挂载容器使用微服务路由作为微服务的挂载容器场景描述微服…...
2|电子技术|数字电子技术基础|雨课堂习题|考前回顾
A/DD/A转化横向与阵列 相乘,竖向为或阵列 相加!功率放大电路克服交越失真,是在乙类的基础上增加两个二极管,使微导通,使三极管导通时间大于半个周期,小于一个周期,构成甲乙类工作状态。选择填空…...
vue+echarts:圆形柱状图设置角度和最大值
第020个点击查看专栏目录本示例是显示圆形的柱状图,angleAxis设置一个max, angleAxis上startAngle:90 , 将0点设置为最顶点。 文章目录示例效果示例源代码(共100行)相关资料参考专栏介绍示例效果 示例源代码…...
Linux系统安装Nginx常见报错问题
安装Nginx从nginx官网下载所需版本的nginx,http://nginx.org/下载之后,将安装包上传到linux系统指定路径解压文件,tar -zxvf nginx-1.22.1.tar.gz (此处用1.22.1版本为例)进入安装包目录,cd nginx-1.22.1执…...
按下按键之后,打印一句话------>三个按键需要实现
main.c: #include "key.h" extern void printf(const char *fmt, ...); void delay_ms(int ms){ int i,j; for(i 0; i < ms;i) for (j 0; j < 1800; j);} int main(){ //key1键盘 //EXIT控制器初始化 void PF9_exti_init(); //GICD控…...
Mac配置VScode
Mac配置VScode 常用技巧 命令调色板 根据您当前的上下文访问所有可用的命令。 键盘快捷键:⇧⌘P 快速打开 快速打开文件。 键盘快捷键:⌘P **提示:**类型?查看命令建议。 在最近打开的文件夹和工作区之间导航 最近打开 键盘快捷…...
MAC地址IP地址 端口
网络结构: 服务器-客户机(C/S)Client-Server结构,如QQ,LOL都拥有客户端 优点:响应速度快,形式多样,安全新较高缺点:安装软件和维护,不能跨平台LINUX/windows/MAC浏览器-…...
关于虚拟数字人你想知道的都在这里
2022年底,微软旗下的人工智能实验室Open AI发布的对话式大型语言模型ChatGPT聊天机器人一夜蹿红,5天用户量超百万,在各大中外媒体平台掀起了一阵热潮。也带火了人工智能相关产业,AI虚拟数字人就是其中之一,一个随着元宇…...
分布式任务调度处理方案(无代码)
业务涉及到,需要向数据库、redis、elasticsearch、MinIO写四份数据,这里存在分布式事务问题。如何解决问题,先分析cap,是要保证可用性,还是保证一致性。如何选择是CP还是AP?分析业务场景CP的场景࿱…...
2023年博管办香江学者计划、澳门青年学者开始申报
2023年2月20日,全国博士后管委会办公室官方网站发出了2023年香江学者计划、澳门青年学者计划和博士后国(境)外学术交流项目申报指南,以下知识人网小编仅转载香江学者计划和澳门青年学者计划申报指南并做重点解读。知识人网整理香江…...
(二十一)、实现评论功能(1)【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】
1,评论回复模块的样式布局 1.1 在detail页面添加uview中的 Empty 内容为空组件 <!-- 评论区 --><view class"comment"><u-empty mode"comment" icon"http://cdn.uviewui.com/uview/empty/comment.png"></u-emp…...
【Docker】初识Dcoker以及镜像操作(一)
目录 1.初识Docker 1.1.什么是Docker 1.1.1.应用部署的环境问题 1.1.2.Docker解决依赖兼容问题 1.1.3.Docker解决操作系统环境差异 1.1.4.小结 1.2.Docker和虚拟机的区别 1.3.Docker架构 1.3.1.镜像和容器 1.3.2.DockerHub 1.3.3.Docker架构 1.3.4.小结 1.4.安装D…...
(1)C#传智:在vs2022中基本了解(第一天)
开始vs2022中C#入门,就是一笔记,算不上原创,没办法得选啊。 一、vs中卸载项目和移除项目有什么区别? 1、卸载、移除都不会移除物理文件,只会删除关联 2、卸载删除关联的程度低,卸载后项目只是“变灰色…...
IA-Lab AI 检测报告生成助手:双碳目标驱动下的检测机构效率引擎,重塑报告生成与合规审核新模式
在“双碳”目标持续推进的时代背景下,绿色发展已从政策导向转变为企业与机构必须面对的现实命题。对于检测认证(TIC)行业而言,这一变化尤为明显——碳排放核算、能源效率评估、环境数据监测等业务需求快速增长,检测报告…...
Amazon日本站、欧洲站A+内容翻译怎么做?跨马翻译在多站点运营中的实际应用
【一、从一次上架被拒说起】上个月帮一个做家居品类的卖家朋友处理欧洲站上架问题,他花了两周精心设计的A页面被Amazon审核退回,原因只有一句话:"Please ensure all images contain text in the target marketplace language."&…...
Golang GORM怎么做Scopes复用_Golang GORM Scopes教程【推荐】
Scopes 是接收并返回 *gorm.DB 的函数,用于链式构建查询;需严格签名、避免提前执行、显式传参、控制分页参数、顺序影响SQL逻辑、事务中注意句柄、不处理错误。Scopes 就是带参数的 func(*gorm.DB) *gorm.DB它不是魔法,就是个普通函数签名——…...
WPF调试神器:如何在GUI应用中优雅地输出Console日志(附完整代码)
WPF调试神器:如何在GUI应用中优雅地输出Console日志(附完整代码) 在WPF开发过程中,调试信息的实时输出是排查问题的关键环节。传统弹窗或文件日志方式要么打断用户体验,要么缺乏即时性。本文将介绍一种兼顾优雅与高效的…...
毕业工具怎么选?一张表对比选题、写作、降重、排版、答辩核心功能
从选题到答辩,选对工具能省下80%的无效劳动。本文聚焦毕业全流程各环节的核心功能,帮你快速定位适合自己的工具组合。一、毕业全流程功能总览一个完整的毕业论文写作流程通常包括以下几个阶段,每个阶段都有对应的工具功能可以提效:…...
Spyglass实战指南:从约束到违例豁免的CDC/RDC检查全流程
1. Spyglass入门:CDC/RDC检查基础 第一次接触Spyglass时,我被它复杂的规则体系搞得晕头转向。直到在项目中真正用它解决了几个棘手的跨时钟域问题,才明白这个工具的价值。简单来说,Spyglass就像个经验丰富的"电路医生"&…...
告别命令行:用 Gradio 为本地大模型打造专属 Web 聊天室
1. 为什么需要给本地大模型加个Web界面? 还在用命令行和你的本地大模型聊天吗?每次打开终端输入命令,看着密密麻麻的文本输出,是不是感觉像是在和一台老式打字机对话?作为一个折腾过各种大模型的开发者,我完…...
别让格式拖垮论文!Paperxie AI 一键盘活你的毕业定稿
paperxie-免费查重复率aigc检测/开题报告/毕业论文/智能排版/文献综述/AIPPThttps://www.paperxie.cn/format/typesettinghttps://www.paperxie.cn/format/typesetting 凌晨两点的宿舍,键盘敲击声断断续续,桌前的本科生盯着屏幕上的论文文档叹气 —— 内…...
别再花钱买Beyond Compare了!用WinMerge搞定二进制文件对比(附详细配置步骤)
用WinMerge实现专业级二进制文件对比:零成本替代收费工具的完整指南 在软件开发和逆向工程领域,二进制文件对比是个高频需求。无论是分析固件更新、检查软件补丁,还是进行安全审计,都需要精确识别文件间的字节级差异。虽然Beyond …...
答辩PPT不用愁,百考通AI助你高效搞定毕业答辩全流程
告别熬夜与焦虑,3分钟生成专业级答辩PPT 临近毕业季,当论文终于定稿,许多同学本以为可以松一口气,却发现自己又面临新的挑战——毕业论文答辩PPT的制作。这最后一关,往往成为不少毕业生的“拦路虎”。 面对几十页的论…...
