Java 编程语言是第一种设计成为全面支持国际化的语言。 《Java 核心技术 卷二》
1. Locale
Locale 类代表一个特定的地理、语言和国家环境。Locale 向一些对国家和语言、地理等比较敏感的类提供国家地区语言信息,这些类有DateFormat、NumberFormat等等。
1.1. Locale 的构成
Locale 核心由2部分构成:
- 语言:由2个或3个小写字母(ISO-639-1)表示。例如:Chinese:zh;
- 国家或地区:由2个大写字母(ISO-3166-1)或三个数字(UN M.49)表示。例如:China:CN;
常见的 ISO-639-1语言代码:
- Chinese:zh
- Japanese:ja
- Italian:it
- English:en
- French:fr
- German:de
- Spanish:es
常见的 ISO-3166-1 国家代码:
- China:CN
- Japan:JP
- Germany:DE
- Canada:CA
1.2. 创建 Locale
Locale 的构造函数:
public Locale(String language) public Locale(String language, String country)
Locale 也预定义了一些国家、语言的 Locale:
// for language Locale.ENGLISTH Locale.FRENCH Locale.JAPANESE Locale.CHINESE Locale.SIMPLIFIED_CHINESE Locale.TRADITIONAL_CHINESE // for country Locale.FRANCE Locale.JAPAN Locale.CHINA
1.3. 获取 Locale
public static Locale getDefault() public static Locale[] getAvailableLocales()
示例1:获取当前 JVM 实例的默认 Locale:
public static void main(String[] args) {
Locale l = Locale.getDefault();
System.out.println(l.getDisplayName());
System.out.println(l.toLanguageTag());
}示例2:获取当前 JVM 支持的所有 Locale:
public static void main(String[] args) {
Locale[] locales = Locale.getAvailableLocales();
for(Locale locale : locales){
System.out.println(locale.getDisplayName()+","+locale.toLanguageTag());
}
}2. Locale 与 Format 间关系
数字、货币、日期的格式是高度依赖 locale 的。Java 类库提供了一个格式器(formatter)对象的集合,用于处理它们的格式化和解析操作。
图2-1:Format 及其实现类
3. NumberFormat
3.1. 概述
类间结构:
图3-1:NumberFormat 与 DecimalFormat
关键信息:
- NumberFormat 是个抽象类;
- DecimalFormat 虽然是 NumberFormat 的子类,但不要自己去 new,应该通过 NumberFormat 的各种 getXXInstance 接口获取实例;
- 如果想使用 DecimalFormat 的特殊接口,可通过向下转型实现。(对于绝大多数Locale,NumberFormat 取到的实例都是 DecimalFormat,但也最好加上 try .. catch)。
- NumberFomart 的各种 getXXInstance 可用于对“整数”、“百分比”、“科学计数”、“数字”的格式化实例。
- 线程不安全。
图3-2:NumberFormat 的各种 getXXInstance() 方法
3.2. 整数格式化(getIntegerInstance())
获取整数格式化器:
NumberFormat integerInstance = NumberFormat.getIntegerInstance();
getIntegerInstance() 帮你预设的格式化、解析参数:
- 解析控制:只解析整数部分
- 格式化控制:小数位数0;
- 格式化控制:不显示小数分隔符;
图3-3:IntegerInstance 预设的控制参数
示例1:简体中文 Locale 下的数字格式化
package webj2ee;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
public class JdkLoggingDemo {
public static void main(String[] args) {
NumberFormat fmt = NumberFormat.getIntegerInstance(Locale.SIMPLIFIED_CHINESE);
// 常规操作
System.out.println(fmt.format(Math.PI));
// 舍入特性:
fmt.setRoundingMode(RoundingMode.HALF_UP); // 四舍五入
System.out.println(fmt.format(3.5));
// 分组特性:
fmt.setGroupingUsed(true);
System.out.println(fmt.format(Integer.MAX_VALUE));
// 控制最大整数位数:
fmt.setMaximumIntegerDigits(5);
System.out.println(fmt.format(Integer.MAX_VALUE));
// 控制最大整数位数:
fmt.setMinimumIntegerDigits(5);
System.out.println(fmt.format(Math.PI));
// ---------------- 向下转型为 DecimalFormat,精细化控制;
DecimalFormat dfmt = (DecimalFormat)fmt;
dfmt.setPositivePrefix("+");
System.out.println(dfmt.format(Math.PI));
System.out.println(dfmt.format(-Math.PI));
}
}
示例2:德国 Locale 下的数字格式化
NumberFormat fmt = NumberFormat.getIntegerInstance(Locale.GERMANY); // ... 后面不变
示例3:德国 Locale 下的数字格式化
NumberFormat fmt = NumberFormat.getIntegerInstance(Locale.FRANCE);
3.2. 货币格式(getCurrencyInstance())
public static void main(String[] args) {
NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.SIMPLIFIED_CHINESE);
System.out.println(fmt.format(Math.PI));
NumberFormat fmt1 = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(fmt1.format(Math.PI));
NumberFormat fmt2 = NumberFormat.getCurrencyInstance(Locale.FRANCE);
System.out.println(fmt2.format(Math.PI));
}3.3. 百分比格式
public static void main(String[] args) {
NumberFormat fmt = NumberFormat.getPercentInstance(Locale.SIMPLIFIED_CHINESE);
fmt.setMinimumFractionDigits(2);
System.out.println(fmt.format(Math.PI/100f));
}4. DateFormat
4.1. 概述
类间结构:
关键信息:
- DateFormat 是个抽象类;
- SimpleDateFormat 虽然是 DateFormat 的子类,但不要自己去 new,应该通过 DateFormat 的各种 getXXInstance 接口获取实例;
- 如果想使用 SimpleDateFormat 的特殊接口,可通过向下转型实现。
- 线程不安全;
示例:
public static void main(String[] args) {
DateFormat fmt = DateFormat.getInstance();
SimpleDateFormat sdf = (SimpleDateFormat)fmt;
sdf.applyPattern("yyyy-MM-dd HH:mm:ss SSS");
String ret = sdf.format(new Date());
System.out.println(ret);
}4.2. Date and Time Patterns
特殊的地方:
- Month:如果用【>=3个 M】描述月份,则月份将被转换为【文字】;
5. MessageFormat
Java 类库中有一个 MessageFormat 类,它与用 printf 方法进行格式化很类似,但是它支持 Locale,并且会对数字和日期进行格式化。
5.1. Patterns and Their Interpretation
5.2. 示例
示例1:
public static void main(String[] args) {
// ArgumentIndex 必须是非负整数,而且它的个数不只限于0到9这10个。
String message = "{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}{16}";
[] array = new []{"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q"};
String value = MessageFormat.format(message, array);
System.out.println(value);
}示例2:
public static void main(String[] args) {
// 格式化字符串时,两个单引号才表示一个单引号,单个单引号会被省略
String message1 = "oh, {0} is 'a' pig";
String message2 = "oh, {0} is ''a'' pig";
[] array = new []{"ZhangSan"};
String value1 = MessageFormat.format(message1, array);
String value2 = MessageFormat.format(message2, array);
System.out.println(value1);
System.out.println(value2);
}示例3:
public static void main(String[] args) {
String message = "oh, {0,number,#.#######} is PI!";
[] array = new []{Math.PI};
String value = MessageFormat.format(message, array);
System.out.println(value);
}参考:
Standard country or area codes for statistical use (M49): https://unstats.un.org/unsd/methodology/m49/ Class MessageFormat: https://docs.oracle.com/javase/8/docs/api/java/text/MessageFormat.html 《Java 核心技术 卷二》 《Java 编程思想》 《Java 8 编程参考官方教程》
继续阅读与本文标签相同的文章
-
关于ssh端口转发
2026-05-27栏目: 教程
-
5 门正在奋力崛起的编程语言
2026-05-27栏目: 教程
-
深度思维,不过是为了余生获得更多的自由
2026-05-27栏目: 教程
-
Mybatis源码解读-设计模式总结
2026-05-27栏目: 教程
-
开源神器!答应我,别再用 abc 做变量名了好么!
2026-05-27栏目: 教程
