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

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

相关文章

  • Springboot解决跨域问题方案总结(包括Nginx,Gateway网关等)

    Springboot解决跨域问题方案总结(包括Nginx,Gateway网关等)

    跨域问题是浏览器为了保护用户的信息安全,实施了同源策略(Same-Origin Policy),即只允许页面请求同源(相同协议、域名和端口)的资源,本文给大家总结了Springboot解决跨域问题方案包括Nginx,Gateway网关等),需要的朋友可以参考下
    2024-03-03
  • Spring中@Primary注解的作用与使用

    Spring中@Primary注解的作用与使用

    本文主要介绍了Spring中@Primary注解的作用与使用,@Primary 注解用于解决依赖注入时的歧义性问题,具有一定的参考价值,感兴趣的可以了解一下
    2025-06-06
  • 简单谈谈ThreadPoolExecutor线程池之submit方法

    简单谈谈ThreadPoolExecutor线程池之submit方法

    下面小编就为大家带来一篇简单谈谈ThreadPoolExecutor线程池之submit方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Java实现单线程聊天室

    Java实现单线程聊天室

    这篇文章主要为大家详细介绍了Java实现单线程聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • Nacos源码之注册中心的实现详解

    Nacos源码之注册中心的实现详解

    这篇文章主要为大家介绍了Nacos源码之注册中心的实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • spring mvc 使用kaptcha配置生成验证码实例

    spring mvc 使用kaptcha配置生成验证码实例

    本篇文章主要介绍了spring mvc 使用kaptcha生成验证码实例,详细的介绍了使用Kaptcha 生成验证码的步骤,有兴趣的可以了解一下
    2017-04-04
  • Java中tomcat memecached session 共享同步问题的解决办法

    Java中tomcat memecached session 共享同步问题的解决办法

    这篇文章主要介绍了Java中tomcat memecached session 共享同步问题的解决办法的相关资料,需要的朋友可以参考下
    2015-10-10
  • Java创建对象的常见方式技术指南

    Java创建对象的常见方式技术指南

    在 Java 开发中,对象是一切面向对象编程的基础,Java 提供了多种方式来创建对象,不同方式背后有不同的应用场景与运行机制,下面哦我们就来深入了解下吧
    2025-06-06
  • springboot @ConfigurationProperties和@PropertySource的区别

    springboot @ConfigurationProperties和@PropertySource的区别

    这篇文章主要介绍了springboot @ConfigurationProperties和@PropertySource的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • SpringBoot详解执行过程

    SpringBoot详解执行过程

    这篇文章主要介绍了SpringBoot的执行过程原理,Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-07-07

最新评论