Java字符串格式化Formatter和printf()的使用详解

 更新时间:2025年05月01日 10:22:36   作者:面朝大海,春不暖,花不开  
这篇文章主要介绍了Java字符串格式化Formatter和printf()的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

在 Java 编程中,字符串格式化是一项基本且重要的技能。它允许开发者以特定的方式将各种类型的数据(如数字、日期、字符串等)转换为字符串,以便于显示、存储或传输。

Java 提供了多种方法来实现字符串格式化,其中最常用的是 String.format()、Java 15 引入的 string.formatted() 实例方法,以及 PrintStreamPrintWriter 类中的 printf() 方法。

这些方法都依赖于 java.util.Formatter 类,该类使用类似于 C 语言 printf() 函数的格式代码。

字符串格式化的方法

Java 提供了三种主要的字符串格式化方法,每种方法都有其特定的使用场景:

1.String.format()

这是一个静态方法,用于创建一个格式化的字符串。它接受一个格式字符串和一系列参数,返回一个格式化后的字符串。适用于需要将格式化结果存储为字符串的场景。

示例:

String str = String.format("Hello %s, today is %tF%n", "World", LocalDate.now());
System.out.println(str);

输出示例:

Hello World, today is 2025-04-27

2.string.formatted()

从 Java 15 开始,字符串实例提供了一个 formatted() 方法,可以直接对字符串进行格式化。其功能与 String.format() 类似,但语法更简洁,适合需要快速格式化的场景。

示例:

String str = "Hello %s, today is %tF%n".formatted("World", LocalDate.now());
System.out.println(str);

输出示例:

Hello World, today is 2025-04-27

3.printf()

PrintStreamPrintWriter 类提供了 printf() 方法,可以直接将格式化的字符串输出到流中(如控制台或文件)。它适合需要立即输出的场景。

示例:

System.out.printf("Hello %s, today is %tF%n", "World", LocalDate.now());

输出示例:

Hello World, today is 2025-04-27

格式字符串的结构

格式字符串由普通字符和格式代码组成。普通字符按原样输出,而格式代码以 % 开头,用于指定如何格式化参数。格式代码的完整结构如下:

% [argument_index$] [flags] [width] [.precision] conversion
  • argument_index$:可选,指定要格式化的参数索引(从 1 开始)。例如,%1$s 表示第一个参数作为字符串。
  • flags:可选,控制输出格式,如 - 表示左对齐,0 表示用 0 填充。
  • width:可选,指定字段的最小宽度。
  • .precision:可选,对于浮点数,指定小数点后位数;对于字符串,指定最大字符数。
  • conversion:必须,指定数据类型,如 d(十进制整数)、f(浮点数)、s(字符串)等。

例如,%04d 表示将整数格式化为至少 4 位,不足时前面补 0;%4.2f 表示浮点数总宽度至少 4 位,小数点后 2 位。

常用格式代码

以下是 java.util.Formatter 类支持的一些常用格式代码:

格式代码含义
%b布尔值(true 或 false)
%c字符
%d十进制整数(无小数点)
%f浮点数(带小数部分)
%s字符串(通用格式)
%t日期/时间(需后跟具体代码)
%n平台相关的换行符
%%字面上的 % 字符

对于某些代码(如 %b%c%s),使用大写形式(如 %S)会将结果转换为大写。

日期和时间格式化

日期和时间格式化使用 %t 前缀,后跟一个字符来指定具体格式。

以下是一些常用的日期/时间格式代码:

格式代码含义
%tA星期几的完整名称(如“星期日”)
%ta星期几的缩写名称(如“周日”)
%tB月份的完整名称(如“一月”)
%tb月份的缩写名称(如“一月”)
%td月份中的天(两位数,如“01”)
%tY年份(至少四位,如“2025”)
%tFISO 8601 日期格式(YYYY-MM-DD)

日期格式化通常与 LocalDateDateCalendar 等对象一起使用。

需要注意的是,当对同一日期对象格式化多个字段时,必须为每个格式代码指定参数索引(如 %1$tY)。

代码示例

以下是一些实际应用中的格式化示例,涵盖数字、字符串和日期。

1. 格式化数字

System.out.printf("%04d - the year of %f%n", 1956, Math.PI);
  • 输出:1956 - the year of 3.141593
  • 说明:%04d 确保年份显示为 4 位,前面补 0;%f 显示浮点数 Math.PI 的完整值。

2. 控制浮点数精度

System.out.printf("PI is approximately %4.2f%n", Math.PI);
  • 输出:PI is approximately 3.14
  • 说明:%4.2f 指定浮点数总宽度至少 4 位,小数点后保留 2 位。

3. 格式化日期

LocalDate today = LocalDate.now();
System.out.printf("Today is %1$tB %1$td, %1$tY%n", today);
  • 输出示例:Today is April 27, 2025
  • 说明:%1$tB 显示月份名称,%1$td 显示日期,%1$tY 显示年份,1$ 确保使用同一个 LocalDate 对象。

4. 使用参数索引重复格式化

System.out.printf("%1$tY-%1$tm-%1$td%n", LocalDate.now());
  • 输出示例:2025-04-27
  • 说明:通过 1$ 指定使用第一个参数(LocalDate.now()),分别提取年、月、日。

5. 写入文件

try (Formatter formatter = new Formatter("output.txt")) {
    formatter.format("Price: $%5.2f%n", 27.99);
}

说明:将格式化结果写入文件 output.txt,内容为 Price: $27.99

最佳实践和注意事项

  • 安全性:避免使用用户提供的格式字符串,因为格式字符串可能被恶意构造,导致安全漏洞。例如,攻击者可能利用格式代码访问不应访问的数据。始终对用户输入进行验证和清理。
  • 国际化:在多语言应用中,直接使用日期格式代码(如 %tB)可能不适合所有地区,因为不同语言对日期的显示顺序和格式有不同要求。建议使用 java.time.format.DateTimeFormatter 来处理国际化日期格式化。
  • 平台无关性:使用 %n 作为换行符,而不是硬编码 \n,因为 %n 会根据运行平台自动选择正确的换行符。
  • 性能:对于高性能场景,避免频繁创建 Formatter 对象。可以复用 Formatter 实例或直接使用 String.format()printf()

关于 StringTemplate 的说明

Java 21 和 22 引入了 StringTemplate 作为预览功能,旨在提供更简洁的字符串插值方式,例如 STR."Hello \{name}"。然而,由于设计上的问题,该功能在 Java 23 中被撤回。根据 Java StringTemplate Discussion,开发团队正在探索更安全和优雅的实现方案,但目前尚无明确的时间表。

总结

Java 的字符串格式化工具通过 Formatter 类及其相关方法,为开发者提供了强大的数据格式化能力。无论是格式化数字、字符串还是日期,String.format()string.formatted()printf() 都能满足各种需求。通过掌握格式代码的结构和用法,开发者可以编写更清晰、更高效的代码。然而,在使用时需注意安全性和国际化问题,以确保代码的健壮性和可移植性。

格式代码种类繁多,本文仅介绍了最常用的部分。欲了解完整列表,请参阅 Java Formatter Documentation

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

相关文章

  • EasyExcel工具读取Excel空数据行问题的解决办法

    EasyExcel工具读取Excel空数据行问题的解决办法

    EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节省内存著称,下面这篇文章主要给大家介绍了关于EasyExcel工具读取Excel空数据行问题的解决办法,需要的朋友可以参考下
    2022-08-08
  • Java填充替换数组元素实例详解

    Java填充替换数组元素实例详解

    这篇文章主要通过两个实例说明Java填充和替换数组中元素的方法,需要的朋友可以参考下。
    2017-08-08
  • java中SpringBoot 自动装配的原理分析

    java中SpringBoot 自动装配的原理分析

    这篇文章主要介绍了SpringBoot 自动装配的原理分析的相关资料,需要的朋友可以参考下
    2022-12-12
  • idea配置gradle全过程

    idea配置gradle全过程

    安装Gradle首先需要解压安装包到指定目录,随后配置环境变量GRDLE_HOME和GRADLE_USER_HOME,这里的GRADLE_USER_HOME是指文件下载的路径,安装后,通过命令行输入gradle -v来测试是否安装成功,对于Idea的配置,需要通过File->Setting->Gradle进行
    2024-10-10
  • MyBatis SpringMVC整合实现步骤详解

    MyBatis SpringMVC整合实现步骤详解

    这篇文章主要介绍了MyBatis SpringMVC整合实现步骤详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Java中的ReentrantReadWriteLock使用详解

    Java中的ReentrantReadWriteLock使用详解

    这篇文章主要介绍了Java中的ReentrantReadWriteLock使用详解,ReentrantReadWriteLock是Java中的一个锁实现,它提供了读写分离的功能,这种读写分离的机制可以提高并发性能,特别适用于读多写少的场景,需要的朋友可以参考下
    2023-11-11
  • SpringMVC中controller接收json数据的方法

    SpringMVC中controller接收json数据的方法

    这篇文章主要为大家详细介绍了SpringMVC中controller接收json数据的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09
  • 浅拷贝和深拷贝原理分析

    浅拷贝和深拷贝原理分析

    Java 对象拷贝是为对象赋值的一种方式,简单来说就是创建一个和原对象相同的对象,新创建的对象是原对象的一个副本。面试官贼拉喜欢在面试的时候问一问你浅拷贝和深拷贝的原理
    2021-08-08
  • Mybatis(ParameterType)传递多个不同类型的参数方式

    Mybatis(ParameterType)传递多个不同类型的参数方式

    这篇文章主要介绍了Mybatis(ParameterType)传递多个不同类型的参数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Spring Boot整合Swagger2的完整步骤详解

    Spring Boot整合Swagger2的完整步骤详解

    这篇文章主要给大家介绍了关于Spring Boot整合Swagger2的完整步骤,文中通过示例代码将整合的步骤一步步介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07

最新评论