在Java开发中,我们经常需要处理字符串拼接——比如生成日志、格式化用户输出、拼接订单号或二维码ID。你可能遇到过这样的代码:
String log = "用户" + username + "在" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "登录,IP地址是" + ip;
这种手动拼接的方式不仅代码冗长,还容易出现格式错误(比如日期格式遗漏、空格错位)。而String.format
作为Java提供的字符串格式化工具,能帮你用更简洁、更可维护的方式解决这些问题。
一、什么是String.format?
String.format
是java.lang.String
类的静态方法,用于将指定参数按照格式字符串的规则拼接成格式化字符串。其语法为:
String.format(String format, Object... args)
format
:格式字符串,包含普通字符和格式说明符(如%d
、%s
)。args
:可变参数列表,用于替换格式说明符中的占位符。
二、格式说明符:String.format的核心
格式说明符是String.format
的“灵魂”,它定义了参数的显示格式。其通用结构为: %[flags][width][.precision]conversion
我们逐一拆解这些组件:
1. 转换类型(conversion
):指定参数类型
conversion
是格式说明符的必填部分,决定了参数的类型和格式化方式。常见类型如下:
类型 | 描述 | 示例参数 | 示例输出 |
---|---|---|---|
%d | 格式化整数(byte/short/int/long) | 123 | "123" |
%s | 格式化字符串(任何对象,调用toString() ) | "Hello" | "Hello" |
%f | 格式化浮点数(float/double) | 123.456 | "123.456000" |
%c | 格式化字符(char) | 'A' | "A" |
%t | 格式化日期/时间(需后续指定子类型) | new Date() | "2024-07-12" (用%tF ) |
2. 宽度(width
):指定输出最小长度
width
是可选部分,表示输出字符串的最小长度。不足部分用空格或指定字符(如0
)填充。
示例:
%5d
:整数占5位,不足用空格填充(123
→" 123"
)。%019d
:整数占19位,不足用0填充(123
→"0000000000000000123"
)
3. 标志(flags
):修改格式化行为
flags
是可选部分,用于调整输出的对齐方式、填充字符等。常见标志如下:
标志 | 描述 | 示例格式 | 示例参数 | 示例输出 |
---|---|---|---|---|
0 | 用0填充宽度不足部分(仅适用于数值) | %05d | 789 | "00789" |
- | 左对齐(默认右对齐) | %-5s | "abc" | "abc " (后面补空格) |
+ | 显示正负号(正数也显示+ ) | %+d | 123 | "+123" |
, | 用逗号分隔千位(仅适用于数值) | %,d | 123456 | "123,456" |
4. 精度(precision
):控制小数或字符串长度
precision
是可选部分,用于:
- 浮点数:指定小数点后的位数(如
%.2f
→保留两位小数)。 - 字符串:指定最大长度(如
%.5s
→取前5个字符)。
示例:
%.2f
:123.456
→"123.46"
(四舍五入)。%.5s
:"HelloWorld"
→"Hello"
(截断前5个字符)。
三、String.format的优势
对比手动拼接,String.format
的优势一目了然:
1. 代码更简洁,可读性更高
手动拼接需要大量+
号和转换方法(如SimpleDateFormat
),而String.format
用格式字符串统一管理格式:
手动拼接:
String orderInfo = "订单号:" + orderId + ",金额:"
+ new DecimalFormat("#,##0.00").format(amount)
+ ",创建时间:"
+ new SimpleDateFormat("yyyy-MM-dd").format(createTime);
用String.format:
String orderInfo = String.format
("订单号:%s,金额:%,.2f,创建时间:%tF", orderId, amount, createTime);
后者的代码更清晰,格式规则一目了然。
2. 可维护性更强
如果需要调整格式(比如将金额的小数位从2位改为3位),只需修改格式字符串中的%.2f
为%.3f
,无需修改参数部分。而手动拼接需要修改DecimalFormat
的实例,容易遗漏。
3. 灵活性更高
String.format
支持多种格式需求,比如:
- 生成固定长度的编号(如
%019d
生成19位二维码ID)。 - 格式化日期(如
%tF
→yyyy-MM-dd
,%tT
→HH:mm:ss
)。 - 处理多语言(结合资源束,将格式字符串放在配置文件中)。
四、String.format的常见使用场景
1. 生成日志信息
日志是String.format
的高频使用场景,它能帮你快速生成结构化的日志:
String log = String.format
("用户%s在%tT登录,IP地址是%s,操作结果:%s", username, new Date(), ip, result);
log.info(log);
输出:用户admin在14:30:00登录,IP地址是192.168.1.100,操作结果:成功
2. 格式化用户输出
在用户界面或API响应中,需要将数据格式化为易读的形式:
String userInfo = String.format("姓名:%s,年龄:%d,邮箱:%s", user.getName(), user.getAge(), user.getEmail());
输出:姓名:张三,年龄:25,邮箱:zhangsan@example.com
3. 生成固定格式的编号
比如订单号、二维码ID需要固定长度,用%0nd
(n为长度)补零:
long qrId = IdWorker.getId(); // 雪花算法生成唯一ID
String formattedQrId = String.format("%019d", qrId); // 格式化为19位,不足用0填充
输出:0000000000123456789
(假设qrId为123456789)
4. 处理日期时间
String.format
结合%t
系列格式说明符,能快速格式化日期:
Date now = new Date(); String dateTime = String.format("当前时间:%tF %tT", now, now); // %tF→yyyy-MM-dd,%tT→HH:mm:ss
输出:当前时间:2024-07-12 14:30:00
五、进阶技巧:让String.format更强大
1. 处理null值
如果参数为null
,%s
会输出"null"
,可以用Objects.toString
替换为默认值:
String name = null; String formattedName = String.format("姓名:%s", Objects.toString(name, "未知"));
输出:姓名:未知
2. 自定义日期格式
%t
系列支持更细粒度的日期格式,比如:
%tY
:四位年份(如2024
)。%tm
:两位月份(如07
)。%td
:两位日期(如12
)。%tH
:24小时制小时(如14
)。%tM
:分钟(如30
)。%tS
:秒(如00
)。
String customDateTime = String.format("当前时间:%tY年%tm月%td日 %tH时%tM分%tS秒", now, now, now, now, now, now);
输出:当前时间:2024年07月12日 14时30分00秒