java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java格式化输出printf()

Java格式化输出printf()解读

作者:RiskAI

这篇文章主要介绍了Java格式化输出printf()解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

本文通过实例详细介绍Java格式化输出 System.out.printf() 方法的使用、参数的含义、格式转换符使用时的注意事项。

1. printf API

// 使用指定的格式字符串和参数将格式化字符串写入入到输出流
public PrintStream printf(String format, Object ... args)
// 基于本地化环境使用指定的格式字符串和参数将格式化字符串写入到输出流
public PrintStream printf(Locale l, String format, Object ... args)

以上2个方法,当 format 为 null 时,抛出 NPE.

2. 参数说明

format

format 是以百分号(%) 开头的格式说明字符串,具体格式如下

 %[argument_index$][flags][width][.precision]conversion

img-01

可选的 argument_index 是十进制整数,表示参数列表中参数的位置。 第一个参数由“ 1$ ”引用,第二个由“ 2$ ” 引用 ,等等。 argument_index 必须紧跟 % 后面,并以 $ 结束。

note: 参数索引值从1开始,而不是从0开始, %1$ 对第一个参数格式化。这就避免了与0标志混淆。

可选 flags 指定格式化输出外观的各种标志。 有效标志集取决于 conversion。

可选 width是正十进制整数,表示要写入到输出的字符个数(注意对于浮点数:也包含小数点所占的1个字和 负数的负号所占的1个字符)当实际字符数小于指定的宽度时,最前面用 flags 指定的标志填充(若未指定,默认用空格)。

eg: v=2.3, %5.2f 输出 5.20 ,且前面包含1个空格。共打印5个字符,整数位1个5,1个小数点,2个精度,长度为4,比指定的宽度少1为,用1个前导空格代替。

可选 precision 是一个非负十进制整数,通常用于限制字符数。 具体行为取决于转换。

conversion (必需) 是一个字符,指示如何格式化参数。 给定参数的有效转换集取决于参数的数据类型。

标志目的示例
+打印正数和负数的符号+3333.33
空格在正数之前添加空格| 3333.33|
0数字前面补0003333.33
-左对齐(不指定-时,默认为右对齐)|3333.33 |
(将负数括在括号内%d,-90输出(90)
,(英文逗号)添加分组分隔符,只对定点浮点数整数部分添加分组分隔符,小数部分不会添加3,333.33
#(对于f格式)包含小数点3,333.
#(对于x或o格式)添加前缀0x或00xcafe
$指定要格式化的参数索引。例如,%1 d d %1 dx 将以十进制和十六进制格式打印第1个参数159 9F
<<格式化前面说明的数值。例如, %d<%x 将以十进制和十六进制打印同一个值159 9F
转换符类型示例转换符类型示例
d十进制整数159s字符串hello
x十六进制整数9fc字符H
o八进制整数237b布尔true
f定点浮点数1.59e+01h散列码42628b2
e指数浮点数tx或Yx日期时间(T强制大写)已经过时,应当改为使用 java.time 类。
g通用浮点数(e和f中较短的一个)——%百分号%
a16进制浮点数0x1.fccdp3n与平台有关的换行符——

补充1: 使用 s 转换符格式化任意的对象

可以使用 s 转换符格式化任意的对象。 对于实现了 Formattable 接口的任意对象,将调用这个对象的 formatTo 方法;否则调用 toString 方法将这个对象转换为字符串。

补充2: String.format()

使用 String.format() 方法可创建一个格式化的字符串,而不打印输出。

API:

public static String format(String format, Object... args)
public static String format(Locale l, String format, Object... args)   

参数和 printf() 中的含义相同。

表3-日期和时间的转换符

Note: 以下格式符已经过时,对于新的代码,应当使用 java.time 包的方法。

eg:

System.out.printf("%tc",new Date()); 

这条语句将用下面的格式打印当前的日期和时间:

Mon Feb 09 18:05:19 PST 2015

下面的转换符前面都必须用 t/T 修饰。

转换符类型示例
c完整的日期和时间Mon Feb 09 18:05:19 PST 2015
FISO 8601日期2015/2/9
D美国格式的日期(月/日/年)02/09/2015
T24小时时间18:05:19
r12小时时间6:05:19
R24小时时间,没有秒18:05
Y4位数字的年(前面补02015
y年的后两位数字(前面补0)15
C年的前两位数字(前面补0)20
B月的完整拼写February
b或h月的缩写Feb
m两位数字的月(前面补0)02
d两位数字的日(前面补0)09
e两位数字的日(前面不补09
A星期几的完整拼写Monday
a星期几的缩写Mon
j三位数的年中第几天(前面补0),在001到366之间069
H两位数字的小时(前面补0),在0到23之间18
k两位数字的小时(前面不补0),在0到23之间18
I两位数字的小时(前面补0),在01到12之间06
l两位数字的小时(前面不补0),在1到12之间6
M两位数字的分钟(前面补0)05
S两位数字的秒(前面补0)19
L三位数字的毫秒(前面补0)047
N九位数字的毫微秒(前面补0)047000000
p上午或下午的标志pm
z从 GMT 起,RFC 822 数字位移-800
Z时区PST
s从格林尼治时间 1970-01-01 00:00:00 起的秒数1078884319
Q从格林尼治时间 1970-01-01 00:00:00 起的毫秒数1078884319047

从上表可以看到,某些格式只给出了指定日期的部分信息。

例如,只有日期或月份。如果需要多次提供日期来分别格式化每一部分就太笨拙了。

为此,可以用一个格式字符串指示要格式化的参数索引。

索引必须紧跟在%后面,并以$终止。

例如,

System.out.printf("%1$s %2$tB %2$te, %2$tY","Due date:",new Date());

会打印

Due date: February 9, 2015

还可以选择使用<标志。它指示前面格式说明中的参数将被再次使用。也就是说,以下语句将产生与前面语句同样的输出结果:

System.out.printf("%1$s %tB %<te, %<tY","Due date:",new Date());

args

args : 格式字符串中格式说明符引用的参数。

如果参数多于格式说明符,则忽略额外参数。

参数的数量是可变的,可以为零。

参数的最大数量受The Java Virtual Machine Specification(java虚拟机规范)定义的Java数组的最大维数限制。

null参数上的行为取决于 conversion(转换符) 。

locale

数字和日期的格式化规则是特定于本地化环境的。

例如,在德国,分组分隔符是点号而不是逗号,另外 Monday被格式化为 Montag。

locale主要用于如何控制应用的国际化行为。

3.printf 使用实例

// +199 199 c7 307 0xc7 0307
System.out.printf("%+d %<d %<x %<o %<#x %<#o\n",199);
// | 23| |23|
System.out.printf("|% d| |%<d|\n",23);
// hello 第5个字符是o,that's true
System.out.printf("%s 第%d个字符是%c,that's %b\n","hello",5,'o',true);
// 15 % 6 = 3
System.out.printf("%2$d %% %1$d = %3$d\n",6,15, 15 % 6);
// |  7.33| |007.33| |7.330000| 0x1.d51eb851eb852p2
System.out.printf("|%6.2f| |%0<6.2f| |%<f| %<a\n",7.33);
// | 211.79| |211.79 |
System.out.printf("|%7.2f| |%<-7.2f|\n",211.79);
// | -211.79| |(211.79)| |(-211.79)|
System.out.printf("|%8.2f| |%<(8.2f| |(%<.2f)|\n",-211.79);
// |-21171.3333| |-21,171.3333| |-2.1171e+04| |-2.117e+04|
System.out.printf("|%.4f| |%<,.4f| |%<.4e| |%<.4g|\n",-21171.3333);
String str = new String("tree");
// Note: %h 格式符输出对象的散列码 和 调用对象的hashCode 得到的值并不相同
// obj %h formatinput: 36739e,hashCode:3568542
System.out.printf("obj %%h formatinput: %h,hashCode:%s\n",str,str.hashCode());
// true 25 0.0032 含
System.out.printf("%s %s %s %s\n",true,25,3.2e-3,'含');
System.out.printf("|%n| \n","world");
System.out.printf("|%n| \n");

输出

+199 199 c7 307 0xc7 0307
| 23| |23|
hello 第5个字符是o,that's true
15 % 6 = 3
|  7.33| |007.33| |7.330000| 0x1.d51eb851eb852p2
| 211.79| |211.79 |
| -211.79| |(211.79)| |(-211.79)|
|-21171.3333| |-21,171.3333| |-2.1171e+04| |-2.117e+04|
obj %h formatinput: 36739e,hashCode:3568542
true 25 0.0032 含
|

|

关于printf 转换符使用的注意事项

eg:

// test in jdk 8,11,14
// Exception in thread "main" java.util.IllegalFormatConversionException: o != java.lang.Float
System.out.printf("%o\n",2.3f);
// Exception in thread "main" java.util.IllegalFormatConversionException: f != java.lang.Integer
System.out.printf("%f\n",25);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文