格式说明符
无论使用哪种方法,其核心都是格式说明符,它的通用语法如下:
%[flags][width][.precision]conversion
- :格式说明符的起始标志。
flags:可选的修饰符,用于控制输出格式(如左对齐、补零等)。width:可选的输出最小宽度。.precision:可选的精度,对于浮点数是小数位数,对于字符串是最大长度。conversion:必需的转换字符,指定如何将参数转换为字符串(如d代表整数,f代表浮点数)。
System.out.printf() - 控制台输出
这是最直接的方法,用于在控制台打印格式化字符串,它不会返回一个新字符串,而是直接输出。
示例代码
public class PrintfExample {
public static void main(String[] args) {
String name = "Alice";
int age = 30;
double score = 95.8756;
boolean isStudent = true;
// 1. 基本类型
System.out.printf("Name: %s, Age: %d%n", name, age);
// 输出: Name: Alice, Age: 30
// %n 是平台无关的换行符,推荐使用
// 2. 浮点数精度控制
System.out.printf("Score: %.2f%n", score);
// 输出: Score: 95.88 (四舍五入)
// 3. 布尔值
System.out.printf("Is a student: %b%n", isStudent);
// 输出: Is a student: true
// 4. 宽度和对齐
System.out.printf("|%10s|%n", "Right"); // 右对齐,默认
// 输出: | Right|
System.out.printf("|%-10s|%n", "Left"); // 左对齐
// 输出: |Left |
// 5. 补零
System.out.printf("ID: %05d%n", 123);
// 输出: ID: 00123
// 6. 格式化日期时间 (Java 8+)
java.time.LocalDateTime now = java.time.LocalDateTime.now();
System.out.printf("Current date and time: %tF %tT%n", now, now);
// 输出: Current date and time: 2025-10-27 15:30:45
// %tF 是 yyyy-MM-dd, %tT 是 HH:mm:ss
}
}
String.format() - 创建格式化字符串
当你需要一个格式化后的字符串并存储在变量中,而不是直接打印时,这个方法非常有用,它的用法和 printf 完全一样,只是返回一个 String 对象。
示例代码
public class StringFormatExample {
public static void main(String[] args) {
String product = "Laptop";
int quantity = 2;
double price = 1200.99;
// 使用 String.format() 创建格式化字符串
String invoiceLine = String.format(
"Product: %-10s | Quantity: %3d | Total: $%7.2f",
product, quantity, quantity * price
);
// 将结果打印出来或用于其他地方
System.out.println(invoiceLine);
// 输出: Product: Laptop | Quantity: 2 | Total: $ 2401.98
}
}
Formatter 类 - 高级格式化
java.util.Formatter 是 printf 和 String.format 背后的核心类,它提供了更底层的控制,允许你将格式化输出写入不同的目标,如 StringBuilder、File 或其他 OutputStream。
示例代码
import java.util.Formatter;
public class FormatterExample {
public static void main(String[] args) {
// 1. 使用 StringBuilder 作为输出目标
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb);
formatter.format("Hello, %s! Your balance is $%.2f.%n", "Bob", 123.456);
formatter.close(); // 记得关闭 Formatter
System.out.println(sb.toString());
// 输出: Hello, Bob! Your balance is $123.46.
// 2. 直接格式化到文件 (需要处理异常)
try (Formatter fileFormatter = new Formatter("output.txt")) {
fileFormatter.format("This line will be written to a file.");
System.out.println("Data written to output.txt");
} catch (Exception e) {
e.printStackTrace();
}
}
}
StringBuilder.append() - 简单拼接
对于非常简单的拼接,StringBuilder 是最高效的选择,它不提供复杂的格式化,但性能很好。
示例代码
public class StringBuilderExample {
public static void main(String[] args) {
String firstName = "John";
int age = 42;
// 使用 StringBuilder 拼接
StringBuilder sb = new StringBuilder();
sb.append("User: ")
.append(firstName)
.append(", Age: ")
.append(age);
String result = sb.toString();
System.out.println(result);
// 输出: User: John, Age: 42
}
}
TextBlock (Java 15+ 预览, Java 17+ 正式) - 多行字符串
对于需要处理多行字符串(如 JSON, XML, SQL 查询)的场景,TextBlock 是一个革命性的改进,它解决了传统字符串中转义字符和缩进的问题。
示例代码
public class TextBlockExample {
public static void main(String[] args) {
// 传统方式:可读性差,转义麻烦
String jsonOld = "{\n" +
" \"name\": \"Alice\",\n" +
" \"age\": 30\n" +
"}";
// TextBlock 方式:直观,保留缩进
String jsonNew = """
{
"name": "Alice",
"age": 30
}
""";
System.out.println("Traditional way:");
System.out.println(jsonOld);
System.out.println("\nTextBlock way:");
System.out.println(jsonNew);
// TextBlock 也可以进行格式化
String name = "Bob";
int id = 101;
String sqlQuery = """
SELECT *
FROM users
WHERE name = '%s' AND id = %d
""".formatted(name, id);
System.out.println("\nFormatted SQL Query:");
System.out.println(sqlQuery);
}
}
常用格式说明符速查表
| 转换符 | 类型 | 示例 |
|---|---|---|
b |
布尔值 | printf("%b", value); |
c |
字符 | printf("%c", 'A'); |
d |
十进制整数 | printf("%d", 123); |
f |
浮点数 | printf("%.2f", 123.456); |
e |
科学计数法 | printf("%e", 123456); |
s |
字符串 | printf("%s", "Hello"); |
t |
日期/时间 | printf("%tF", date); |
n |
平台无关的换行符 | printf("Hello%nWorld"); |
x |
十六进制整数 | printf("%x", 255); |
o |
八进制整数 | printf("%o", 255); |
常用 Flags:
- 左对齐
- 输出正负号
0:数字前补零- 每三位用逗号分隔(千位分隔符)
总结与最佳实践
| 方法 | 用途 | 优点 | 缺点 |
|---|---|---|---|
System.out.printf() |
直接向控制台输出 | 简单直接,适合调试 | 只能输出,不能保存结果 |
String.format() |
创建格式化字符串 | 灵活,可存储和传递 | 创建了新的 String 对象 |
Formatter |
高级、多目标输出 | 功能强大,可写入文件等 | 代码稍显繁琐,需要手动管理资源 |
StringBuilder |
高性能简单拼接 | 性能最优,无格式化开销 | 不支持格式化,需手动处理拼接逻辑 |
TextBlock |
处理多行字符串 | 可读性极高,天然支持缩进 | 仅限 Java 17+,主要用于静态文本 |
如何选择?
- 只是想在控制台打印调试信息? ->
System.out.printf()是最快的选择。 - 需要生成一个格式化的字符串并保存或传递? ->
String.format()是标准答案。 - 需要处理大量字符串拼接,性能是关键? ->
StringBuilder.append()。 - 需要编写 JSON, HTML, SQL 等多行文本? ->
TextBlock是不二之选,可读性完胜。 - 需要将格式化结果写入文件或网络流? -> 使用
java.util.Formatter。
对于绝大多数日常开发,String.format() 和 TextBlock (如果项目环境允许) 是最常用和最推荐的方法。
