一、方法定义
String.format()
是 Java 中用于格式化字符串的静态方法,它返回一个格式化后的 String
对象,不会修改原始字符串。
方法签名
public static String format(String format, Object... args)
public static String format(Locale l, String format, Object... args)
format
: 包含格式说明符的字符串模板。args
: 要插入到格式字符串中的参数(可变参数)。l
(可选): 指定的Locale
,用于控制数字、日期等的本地化格式。
二、功能说明
String.format()
的功能类似于 C 语言中的 printf()
,允许你通过占位符将变量插入到字符串中,并对输出格式进行精细控制,例如:
- 数值格式化(整数、浮点数)
- 字符串对齐(左对齐、右对齐)
- 日期时间格式化
- 进制转换(十六进制、八进制等)
- 百分比、货币符号等
三、格式说明符语法
格式说明符的一般形式为:
%[argument_index$][flags][width][.precision]conversion
组成部分 | 说明 |
---|---|
% |
转义字符,表示格式说明符开始 |
argument_index$ |
参数索引(从1开始),如 1$ , 2$ |
flags |
格式标志,如 - (左对齐)、+ (显示符号)等 |
width |
最小字段宽度 |
.precision |
精度(对浮点数是小数位数,对字符串是最大长度) |
conversion |
转换类型,如 d , f , s 等 |
四、常用转换类型(conversion)
转换符 | 类型 | 示例 |
---|---|---|
%d |
十进制整数 | String.format("%d", 123) → "123" |
%f |
浮点数 | String.format("%.2f", 3.1415) → "3.14" |
%s |
字符串 | String.format("Hi, %s", "Alice") → "Hi, Alice" |
%c |
字符 | String.format("Char: %c", 'A') → "Char: A" |
%b |
布尔值 | String.format("%b", true) → "true" |
%x |
十六进制整数 | String.format("%x", 255) → "ff" |
%n |
换行符(平台无关) | String.format("Line1%nLine2") |
%% |
百分号本身 | String.format("Score: %d%%", 95) → "Score: 95%" |
五、示例代码
1. 基本使用
String name = "Bob";
int age = 25;
double salary = 50000.50;
String info = String.format("Name: %s, Age: %d, Salary: %.2f", name, age, salary);
System.out.println(info);
// 输出: Name: Bob, Age: 25, Salary: 50000.50
2. 参数索引重用
String result = String.format("%1$s loves %1$s's %2$s", "Alice", "cat");
System.out.println(result);
// 输出: Alice loves Alice's cat
3. 对齐与填充
String left = String.format("|%-10s|", "Left"); // 左对齐,宽度10
String right = String.format("|%10s|", "Right"); // 右对齐,宽度10
System.out.println(left); // |Left |
System.out.println(right); // | Right|
4. 数字格式化
double pi = 3.1415926;
System.out.println(String.format("Pi: %.3f", pi)); // Pi: 3.142
System.out.println(String.format("Hex: %x", 255)); // Hex: ff
System.out.println(String.format("Padded: %05d", 42)); // Padded: 00042
5. 本地化格式(Locale)
import java.util.Locale;
double amount = 1234567.89;
System.out.println(String.format(Locale.US, "US: %,f", amount)); // US: 1,234,567.890000
System.out.println(String.format(Locale.GERMANY, "DE: %,f", amount)); // DE: 1.234.567,890000
六、使用技巧
- 重用参数:使用
n$
语法避免重复传参。 - 跨平台换行:使用
%n
替代\n
,确保平台兼容性。 - 精度控制:对浮点数使用
%.2f
控制小数位。 - 零填充:使用
%05d
实现数字补零。 - 条件格式化:结合三元运算符动态生成格式字符串。
七、常见错误
错误 | 原因 | 修复 |
---|---|---|
MissingFormatArgumentException |
参数数量不足 | 检查占位符数量与参数数量是否匹配 |
IllegalFormatConversionException |
类型不匹配,如 %d 用于 String |
确保转换符与参数类型一致 |
UnknownFormatConversionException |
使用了非法转换符,如 %z |
检查转换符拼写 |
IllegalArgumentException |
格式字符串语法错误 | 检查 % 是否正确转义(%% ) |
示例错误:
String.format("%d", "hello"); // 错误:String 不能用于 %d
String.format("%s %s", "only one"); // 错误:参数不足
八、注意事项
- 性能开销:
String.format()
比字符串拼接(+
)或StringBuilder
慢,避免在高频循环中使用。 - 空值处理:传入
null
时,%s
会输出"null"
字符串,而非抛出异常。 - 线程安全:
String.format()
是线程安全的,因为返回新字符串。 - Locale 敏感:数字、货币格式受
Locale
影响,国际化时需注意。 - 不可变性:返回新字符串,原字符串不变。
九、最佳实践
- ✅ 复杂格式化时使用:当需要对齐、补零、精度控制时优先使用。
- ✅ 日志与输出格式化:适合生成用户可读的报告、日志消息。
- ✅ 结合
Locale
处理国际化:如货币、数字格式。 - ✅ 使用
%n
换行:保证跨平台兼容性。 - ✅ 参数索引提高可读性:当参数重复使用时,用
1$
,2$
明确意图。
十、性能优化建议
避免循环中频繁调用:
// ❌ 低效 for (int i = 0; i < 1000; i++) { String s = String.format("Item %d", i); } // ✅ 高效(使用 StringBuilder) StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.append("Item ").append(i).append("\n"); }
缓存格式字符串:如果格式固定,可定义为常量。
考虑
MessageFormat
:对于复杂模板或需要动态参数顺序,可考虑java.text.MessageFormat
。
十一、总结
要点 | 说明 |
---|---|
核心用途 | 格式化字符串,支持类型转换、对齐、精度控制等 |
优势 | 功能强大、可读性高、支持本地化 |
劣势 | 性能低于字符串拼接,语法复杂易出错 |
适用场景 | 日志、报告、用户界面输出、复杂格式需求 |
慎用场景 | 高频循环、性能敏感代码 |
替代方案 | + 拼接、StringBuilder 、String.join() 、Text Blocks (Java 15+) |
✅ 一句话掌握:
String.format()
是 Java 中功能最全面的字符串格式化工具,适合生成结构化、美观的输出;但在性能敏感场景应避免滥用,优先使用StringBuilder
或字符串拼接。