可以使用 System.out.println() 将数值输出到控制台。如下列语句,但是这条语句会将 x 类型所允许的最大非 0 数位个数打印输出 x。
double x = 10000.0 / 3;
System.out.println(x); // 打印 3333.3333333333335
在实际应用中(例如现实元、角和分)显示是有问题的。Java 5 沿用了 C 语言函数中的 printf 方法。
double x = 10000.0 / 3;
System.out.printf("%8.2f", x); // 打印 " 3333.33"
会以一个字段宽度(field width)打印 x: 包括 8 个字符,另外精度为小数点后 2 个字符。会打印一个前导的空格和 7 个字符。
printf 方法提供了多个参数
System.out.printf("你好,%s。明年就 %d 岁了。", name, age);
每一个以 % 字符开始的格式说明符都用相应的参数替换。格式说明符尾部的转换符指示要格式化的数值的类型。
用于 printf 的转换符
转换符 | 类型 | 举例 |
---|---|---|
d | 十进制整数 | 159 |
x | 十六进制整数 | 9f |
o | 八进制整数 | 237 |
f | 定点浮点数 | 15.9 |
e | 指数浮点数 | 1.59e+01 |
g | 通用浮点数(e 和 f 中较短的一个) | 一 |
a | 十六进制浮点数 | 0x1.fccdp3 |
s | 字符串 | Hello |
c | 字符 | H |
b | 布尔 | True |
h | 散列码 | 42628b2 |
tx 或 Tx | 日期时间(T 强制大写) | 已经过时,应当改为使用 java.time 类 |
% | 百分号 | % |
n | 与平台有关的行分隔符 |
可以给出控制格式化输出的各种标志。例如,逗号标志增加了分组的分隔符。
double x = 10000.0 / 3;
System.out.printf("%,.2f", x); // 打印 3,333.33
用于 printf 的标志
标志 | 目的 | 举例 |
---|---|---|
+ | 打印正数和负数的符号 | +3333.33 |
空格 | 在正数之前添加空格 | | 3333.33| |
0 | 数字前面补 0 | 003333.33 |
- | 左对齐 | |3333.33 | |
( | 将负数括在括号内 | (3333.33) |
, | 添加分组分隔符 | 3,333.33 |
# (对于 f 格式) | 包含小数 | 3,3333. |
# (对于 x 或 0 格式) | 添加前缀 0x 或 0 | 0xcafe |
$ | 给定被格式化的参数索引。例如,%1$d, %1$x 将以十进制和十六进制格式打印第一个参数 |
159 9F |
< | 格式化前面说明的数值。例如,%d%<x 以十进制和十六进制打印同一个值 |
159 9F |
可以使用 s 转换符格式化任意的对象。对于任意实现了 Formattable 接口的对象都将调用 formatTo 方法;否则将调用 toString 方法,toString 方法可以将对象转换为字符串。
可以使用静态的 String.format 方法创建一个格式化的字符串,而不打印输出:
String message = String.format("你好,%s。明年就 %d 岁了。", name, age);
下面介绍 printf 方法中日期与时间的格式化选项。格式化包括以 t
开始。
日期和时间的转换符
转换符 | 类型 | 举例 |
---|---|---|
c | 完整的日期和时间 | 星期二 八月 29 13:23:13 CST 2017 |
F | ISO 8601 日期 | 2017-08-29 |
D | 美国格式日期(月/日/年) | 08/29/17 |
T | 24 小时时间 | 13:23:13 |
r | 12 小时时间 | 01:23:13 下午 |
R | 24 小时时间没有秒 | 13:23 |
Y | 4 位数字的年(前面补 0) | 2017 |
y | 年的后两位数字(前面补 0) | 17 |
C | 年的前两位数字(前面补 0) | 20 |
B | 月的完整拼写 | 八月 |
b 或 h | 月的缩写 | 八月 |
m | 两位数字的月(前面补 0) | 08 |
d | 两位数字的日(前面补 0) | 09 |
e | 两位数字的日(前面不补 0) | 9 |
A | 星期几的完整拼写 | 星期二 |
a | 星期几的缩写 | 星期二 |
j | 三位数的年中的日子(前面补 0),在 001 到 366 之间 | 241 |
H | 两位数字的小时(前面补 0),在 0 到 23 之间 | 13 |
k | 两位数字的小时(前面不补 0),在 0 到 23 之间 | 13 |
I | 两位数字的小时(前面补 0),在 0 到 12 之间 | 01 |
l | 两位数字的小时(前面不补 0),在 0 到 12 之间 | 1 |
M | 两位数字的分钟(前面补 0) | 23 |
S | 两位数字的秒(前面补 0) | 13 |
L | 三位数字的毫秒(前面补 0) | 740 |
N | 九位数字的毫微秒(前面补 0) | 740000000 |
p | 上午或下午的标志 | 下午 |
z | 从 GMT 起,RFC822 数字位移 | +0800 |
Z | 时区 | CST |
s | 从格林威治时间 1970-01-01 00:00:00 起的秒数 | 1503984193 |
Q | 从格林威治时间 1970-01-01 00:00:00 起的毫秒数 | 1503984193740 |
可以使用一个格式字符串指示要格式化的参数索引。索引必须紧跟在 % 后面,并以 $ 终止。
System.out.printf("%1$s %2$tY-%2$tm-%2$td %2$tH:%2$tM:%2$tS.%2$tN", "北京时间: ", new Date());
// 打印 北京时间: 2020-08-27 20:02:56.902000000
参数索引从 1 开始,而不是从 0 开始,%1$... 对第 1 个参数格式化。
还可以选择使用 <
标志。它指示前面格式说明中的参数将被再次使用。下列语句将产生与前面语句同样的输出结果:
System.out.printf("%s %tY-%<tm-%<td %<tH:%<tM:%<tS.%<tN", "北京时间: ", new Date());
// 打印 北京时间: 2020-08-27 21:49:47.772000000