Java 能对创建格式化输出进行支持的核心在于 Formatter 类。该类提供了格式转换功能,从而可以采用您所喜欢的各种方式显示数字、字符串以及时间和日期。 《Java 8 编程参考官方教程》
1. Formatter 的缓冲特性
Formatter 通过将程序使用的数据的二进制形式转换成格式化的文本进行工作,这个格式化动作在“缓冲区”中进行,可以让 Formatter 自动提供这个缓冲区,也可以在创建 Formtter 对象时显式提供。
// 几个重要构造函数: public Formatter() public Formatter(Appendable a) public Formatter(String fileName) public Formatter(String fileName, String charset) public Formatter(File file, String csn) public Formatter(PrintStream ps) public Formatter(OutputStream os) public Formatter(OutputStream os, String csn) // 几个重要的成员函数 public void flush() public void close() public Appendable out()
图1-1:接口 Appendable 有哪些常见实现类
示例:
package webj2ee.format;
import java.io.PrintStream;
import java.util.Formatter;
public class FormatterDemo {
public static void main(String[] args) {
PrintStream sysout = System.out;
Formatter fmt = new Formatter(sysout);
fmt.format("Hello world! This is %s!", "Webj2ee");
fmt.close();
}
}2. 格式化的基础知识
在创建完 Formatter 对象之后,就可以使用 Formatter 对象创建格式化字符串了。
public Formatter format(String format, ... args)
format 包含两种类型的条目:
- 第一种类型是由将被简单地复制到缓冲区中的字符构成。
- 第二种类型包含【格式说明符】,格式说明符定义了显式后续参数的方式。
【格式说明符】最简单的形式:
%[格式转换说明符]:格式转换说明符都由单个字符构成。 例如:%f、%e ...
常用格式转换说明符对照表:
示例1:
package webj2ee.format;
import java.io.PrintStream;
import java.util.Date;
import java.util.Formatter;
public class FormatterDemo {
public static void main(String[] args) {
PrintStream sysout = System.out;
Formatter fmt = new Formatter(sysout);
fmt.format("布尔型: %b
" +
"字符型: %c
" +
"十进制整数: %d
" +
"十进制浮点数: %f
" +
"科学计数法: %e
" +
"八进制: %o
" +
"十六进制: %x
" +
"日期: %tc
" +
"字符串: %s",
true, 'W', 1314, Math.PI,
Math.PI, 1314, 1314,
new Date(), "Hello world!");
fmt.close();
}
}3. 格式化时间、日期
时间、日期的格式化通过%t转换说明符描述。但%t与其他说明符的工作方式有些不同,需要使用后缀来描述时间和日期所期望的组成部分和精确格式。
示例:
public class FormatterDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
PrintStream sysout = System.out;
Formatter fmt = new Formatter(sysout);
// 注1: x$ 代表参数索引,参数索引是以 $ 结尾,在 % 后面的数字,用于指定在参数列表中的参数。
// 参数索引从 1 开始。
// 注2: %tL 代表毫秒(000 ~ 999)
fmt.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS %1$tL", new Date());
fmt.close();
}
}4. 控制最小宽度、对其输出
%符号和格式转换代码之间的整数被作为【最小字段宽度说明符】,这会使用空格填充输出,以确保输出达到特定的【最小长度】。默认使用空格进行填充。如果希望使用0进行填充,可以在字段宽度说明符之前放置一个0。
%5d: 按十进制整数格式化,最小5位,使用空格补齐; %05d:按十进制整数格式化,最小5位,使用0补齐;
在默认情况下,所有输出都是右对齐的。紧随%之后放置一个减号,可以强制输出左对齐。
%-5d: 按十进制整数格式化,最小5位,使用空格补齐,左对齐
示例1:九九乘法表
public static void main(String[] args) {
PrintStream sysout = System.out;
Formatter fmt = new Formatter(sysout);
for(int i=1; i<=9; i++){
for(int j=1; j<=i; j++){
fmt.format("%d*%d=%-2d ", i, j, i * j);
}
fmt.format("%n"); // %n 指代一个换行符;使用
也行;
}
fmt.close();
}示例2:十六机制转储工具
package webj2ee.format;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.Formatter;
public class FormatterDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "笨蛋自以为聪明,聪明人才知道自己是笨蛋。";
dump(s.getBytes("UTF-8"));
}
public static void dump(byte[] bytes) {
PrintStream sysout = System.out;
Formatter fmt = new Formatter(sysout);
int n = 0;
for (byte b : bytes) {
if (n % 16 == 0) {
fmt.format("%05x: ", n);
}
fmt.format("%02x ", b);
n++;
if (n % 16 == 0) {
fmt.format("%n");
}
}
fmt.close();
}
}5. 控制精度
【精度说明符】可以应用于 %f、%e 以及 %s 格式说明符。精度说明符位于【最小字段宽度说明符】(如果有的话)之后,由一个小数点以及紧跟其后的整数构成。精度说明符的确切含义取决于所应用数据的类型。
- 当精度说明符应用于使用%f或%e说明符的浮点数时,精度说明符决定了显示的小数位数。
- 如果应用于字符串,那么精度说明符可以指定【最大字段宽度】。
示例1:控制浮点数精度
public static void main(String[] args) {
PrintStream sysout = System.out;
Formatter fmt = new Formatter(sysout);
fmt.format("%.10f", Math.PI);
fmt.close();
}示例2:控制字符串最大长度
public static void main(String[] args) {
PrintStream sysout = System.out;
Formatter fmt = new Formatter(sysout);
fmt.format("%.10s", "This is a very long message!");
fmt.close();
}6. 还有什么跟 Formatter 有关系?
- String.format() 内部用的就是 Formatter;
- System.out.format() 也是;
public static void main(String[] args) {
System.out.format("Hello world, this is %s!", "Webj2ee");
}参考:
《Java 8 编程参考官方教程》 《Java 编程思想》
继续阅读与本文标签相同的文章
-
关于ssh端口转发
2026-05-27栏目: 教程
-
5 门正在奋力崛起的编程语言
2026-05-27栏目: 教程
-
深度思维,不过是为了余生获得更多的自由
2026-05-27栏目: 教程
-
Mybatis源码解读-设计模式总结
2026-05-27栏目: 教程
-
开源神器!答应我,别再用 abc 做变量名了好么!
2026-05-27栏目: 教程
