这几天在编写示例代码的时候经常会用到 System.out.printf() ,因为方便打印各种参数以及执行结果。为啥要用这个方法呢,最常用的不是 System.out.println() 吗?其实 System.out.printf() 对应的实现中用到了和 String.format() 相同的 Formatter.class ,所以平时使用过 String.format() 的同学在使用 System.out.printf() 自然可以很顺利的完成编写。但是,可能有的同学没有使用过 String.format() 更不常用 System.out.printf() ,所以使用起来对某些占位符比较陌生,接下来我们一起来对这里面的占位符以及使用进行梳理 ,帮助大家巩固他们的用法。
System.out.printf()
// java.util.Formatter 和 String.format() 采用的 Formatter 相同
private Formatter formatter;
/**
* 使用指定的格式字符串和参数将格式化字符串写入此输出流。 始终使用的语言环境是 local.getdefault() 返回的语言环境,而与之前对该对象调用其他格式化方法无关。
*
* @param format - 格式字符串语法中描述的格式字符串
* @param args — 格式说明符在格式字符串中引用的参数。如果参数多于格式说明符,则忽略额外的参数。参数的数量是可变的,可以为零。参数的最大数量受到 Java™虚拟机规范定义的 Java 数组的最大维数的限制。空参数的行为取决于转换。
* @return 此输出流
* @throws java.util.IllegalFormatException 如果格式字符串包含非法语法、与给定参数不兼容的格式说明符、给定格式字符串的参数不足或其他非法条件。有关所有可能的格式化错误的规范,请参阅formatter类规范的详细信息部分。
* @throws NullPointerException —— 如果格式为null
*/
public PrintStream format(String format, Object ... args) {
try {
synchronized (this) {
ensureOpen();
if ((formatter == null)
|| (formatter.locale() != Locale.getDefault()))
formatter = new Formatter((Appendable) this);
formatter.format(Locale.getDefault(), format, args);
}
} catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
} catch (IOException x) {
trouble = true;
}
return this;
}
String.format()
/**
* 使用指定的格式字符串和参数返回格式化字符串。 始终使用的语言环境是 local.getdefault() 返回的语言环境。
*
* @param 格式字符串
* @param 格式说明符在格式字符串中引用的参数。如果参数多于格式说明符,则忽略额外的参数。参数的数量是可变的,可以为零。参数的最大数量受到 Java™ 虚拟机规范定义的 Java 数组的最大维数的限制。空参数的行为取决于转换。
*
* @throws java.util.IllegalFormatException 如果格式字符串包含非法语法、与给定参数不兼容的格式说明符、给定格式字符串的参数不足或其他非法条件。有关所有可能的格式化错误的规范,请参阅 formatter 类规范的详细信息部分。
*
* @return 一个格式化的字符串
*
* @see java.util.Formatter
*/
public static String format(String format, Object... args) {
return new Formatter().format(format, args).toString();
}
由上面的源码可以看出,他们的具体实现几乎一致。
在平时的开发过程中,可能会遇到这样的需求:要求给前端输出一段提示性语句,但是语句中包含动态的数据(客户昵称、性别、地址等等)。由于只是在某个场景下的固定格式的提示性语句,所以我们可以选择返回一段字符串给前端进行展示即可,至于动态数据,我们采用 String.format() 处理一下不就好了,是不是感觉简单多啦。
String.format() 字符串格式化的方式有下面两种:
-
format(String format, Object… args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字符串。
-
format(Locale locale, String format, Object… args) 使用指定的语言环境,制定字符串格式和参数生成格式化的字符串。
当然,默认情况下,我们使用的是第一种。
常用的转换符
转换符 | 详细说明 | 替换参数示例 |
---|---|---|
%s | 字符串类型 | “我喜欢~” |
%c | 字符类型 | ‘m’ |
%b | 布尔类型 | true |
%d | 整数类型(十进制) | 88 |
%x | 整数类型(十六进制) | FF |
%o | 整数类型(八进制) | 77 |
%f | 浮点类型 | 8.888 |
%a | 十六进制浮点类型 | FF.35AE |
%e | 指数类型 | 9.38e+5 |
%g | 通用浮点类型(f和e类型中较短的) | 1.88995 |
%h | 散列码 | A |
%% | 百分比类型 | %(%特殊字符%%才能显示%) |
%n | 换行符 | |
%tx | 日期与时间类型(x代表不同的日期与时间转换符) |
搭配转换符
标志符 | 说明 | 示例 | 结果 |
---|---|---|---|
+ | 为正数或者负数添加符号 | (“%+d”,15) | +15 |
− | 左对齐 | (“%-5d”,15) | 15 |
0 | 数字前面补0 | (“%04d”, 99) | 0099 |
空格 | 在整数之前添加指定数量的空格 | (“% 4d”, 99) | 99 |
, | 以“,”对数字分组 | (“%,f”, 9999.99) | 9,999.990000 |
( | 使用括号包含负数 | (“%(f”, -99.99) | (99.990000) |
# | 如果是浮点数则包含小数点,如果是16进制或8进制则添加0x或0 | (“%#x”, 99) (“%#o”, 99) |
0x63 0143 |
< | 格式化前一个转换符所描述的参数 | (“%f和%< 3.2f”, 99.45) | 99.450000和99.45 |
$ | 被格式化的参数索引 | (“%1 d , d,%2 d,s”, 99,“abc”) | 99,abc |
日期和时间转换符
转换符 | 说明 | 示例 |
---|---|---|
c | 包括全部日期和时间信息 | 星期六 十月 27 14:21:20 CST 2020 |
F | “年-月-日”格式 | 2020-10-27 |
D | “月/日/年”格式 | 10/27/20 |
r | “HH:MM:SS PM”格式(12时制) | 02:25:51 下午 |
T | “HH:MM:SS”格式(24时制) | 14:28:16 |
R | “HH:MM”格式(24时制) | 14:28 |
— | — | — |
H | 2位数字24时制的小时(不足2位前面补0) | 15 |
I | 2位数字12时制的小时(不足2位前面补0) | 03 |
k | 2位数字24时制的小时(前面不 |