Formatter类提供了对布局对齐和排列的支持,以及对数值、字符串和日期、时间数据的常规格式和特定于语言环境的输出的支持。通用Java类型,诸如byte、BigDecimal和Calendar都被支持。

Java语言格式化后的字符串很像C语言的printf函数,但比C语言严谨,比如,C语言忽略无效参数,而Java则会抛出异常。同时它也不是为多线程设计的,程序员需要自己考虑同步的问题。

一. 语法

1. 常规类型、字符类型和数值类型的格式说明符语法如下:
%[argument_index$][flags][width][.precision]conversion

2. 用来表示日期和时间类型的格式说明符语法如下:
%[argument_index$][flags][width]conversion

3. 与参数不对应的格式说明符语法如下:
%[flags][width]conversion

-argument_index 可选参数,是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$" 表示,第二个参数由 "2$" 表示,依此类推。

-flags 可选参数,是修改输出格式的字符集。有效标志集取决于转换类型。

-width 可选参数,是一个非负十进制整数,表明要向输出中写入的最少字符数。

-precision 可选参数,是一个非负十进制整数,通常用来限制字符数。特定行为取决于转换类型。

-conversion 必须参数,是一个表明应该如何格式化参数的字符。给定参数的有效转换集取决于参数的数据类型。

二. 参数详解

1. Argument Index 

是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$" 表示,第二个参数由 "2$" 表示,依此类推。

2. Flags

 Flag  General  Character  Integral  Floating Point  Date/Time Description
 '-' y        y       y y y 结果将是左对齐的
 '#'  y1  - y3 y -

结果应该使用依赖于转换类型的替换形式

 '+' -  - y4 y -

结果总是包括一个符号

 '  ' -  - y4 y -

对于正值,结果中将包括一个前导空格

 '0' - - y y -

结果将用零来填充

 ',' - - y2 y5 - 结果将包括特定于语言环境的组分隔符
 '(' - - y4 y5 -

结果将是用圆括号括起来的负数

 y  取决于 Formattable 的定义。

 y  只适用于 'd' 转换。

 y3    只适用于 'o'、'x' 和 'X' 转换。

 y4  对 BigInteger 应用 'd'、'o'、'x' 和 'X' 转换时,或者对 byte 及 Byte、short 及 Short、int 及 Integer、long 及 Long 分别应用 'd' 转换时适用。

 y5  只适用于 'e'、'E'、'f'、'g' 和 'G' 转换。

任何未显式定义为标志的字符都是非法字符,并且都被保留,以供扩展使用。

3. Width

width表示输出字符的最少字符数。被格式化参数用precision截取器截取后与width相比,被格式化参数字符数如果小于width,则加字符则到width。在行分隔符转换(line separator conversion)中,width被禁止使用。

4. Precision

  1. 对于常规类型,precision表示输出字符的最大字符数。
  2. 对浮点类型转换'e', 'E',和'f',precision小数点的几位数字。如果转换是'g'或'G',precision表示取整后的全部数字。如果转换是'a'或'A',precision被禁止使用。
  3. 对字符、整型的、日期和时间类型,precision被禁止使用。

5. Conversions 

转换字符大致可分为如下几类:

  1. 常规(General)- 可应用于任何参数类型
  2. 字符(Character)- 可应用于表示 Unicode 字符的基本类型:char、Character、byte、Byte、short 和 Short。当 Character.isValidCodePoint(int) 返回 true 时,可将此转换应用于 int 和 Integer 类型。
  3. 数值(Numeric)
    1)整数(Integral)- 可应用于 Java 的整数类型:byte、Byte、short、Short、int、Integer、long、Long 和 BigInteger
    2)浮点(Floating Point)- 可用于 Java 的浮点类型:float、Float、double、Double 和 BigDecimal
  4. 日期/时间(Date/Time)- 可应用于 Java 的、能够对日期或时间进行编码的类型:long、Long、Calendar 和 Date
  5. 百分比(Percent)- 产生字面值 '%' ('\u0025')
  6. 行分隔符(Line Separator)- 产生特定于平台的行分隔符

大写转换符(也就是: 'B', 'H''S', 'C', 'X', 'E', 'G''A', and 'T')在功能上与其小写是一样的,只不过在输出时将结果转换为大写。相当于对结果调用:String.toUpperCase()

Conversion Argument Category Description
'b', 'B' 常规(General) 如果参数 arg 为 null,则结果为 "false"。如果 arg 是一个 boolean 值或 Boolean,则结果为 String.valueOf() 返回的字符串。否则结果为 "true"。
'h', 'H' 常规(General) 如果参数 arg 为 null,则结果为 "null"。否则,结果为调用 Integer.toHexString(arg.hashCode()) 得到的结果。
's', 'S' 常规(General) 如果参数 arg 为 null,则结果为 "null"。如果 arg 实现 Formattable,则调用 arg.formatTo。否则,结果为调用 arg.toString() 得到的结果。
'c', 'C' 字符(Character)

结果是一个 Unicode 字符

'd' 整数(Integral)

结果被格式化为十进制整数

'o' 整数(Integral)

结果被格式化为八进制整数

'x', 'X' 整数(Integral)

结果被格式化为十六进制整数

'e', 'E' 浮点(Floating Point)

结果被格式化为用计算机科学记数法表示的十进制数

'f' 浮点(Floating Point) 结果被格式化为十进制数
'g', 'G' 浮点(Floating Point) 结果被格式化为十进制数
'a', 'A' 浮点(Floating Point)

结果被格式化为带有效位数和指数的十六进制浮点数

't', 'T' 日期/时间(Date/Time)

日期和时间转换字符的前缀,后缀参考下面的时间、日期转换字符

'%' 百分比(Percent)

结果为字面值 '%'

'n' 行分隔符(Line Separator)

结果为特定于平台的行分隔符

下面三张表分别表示日期、时间、通用转换字符后缀。作为上表't','T'转换字符的补充。

5.1 时间转换字符

'H' 两位数表示的24小时制时间格式,也就是:00-23
'I' 两位数表示的12小时制时间格式,也就是:01-12
'k' 24小时制时间格式,也就是:0-23
'l' 12小时制时间枨,也就是1-12
'M' 两位数表示的分钟格式,也就是:00-59
'S' 两位数表示的秒格式,也就是:00-60(("60" is a special     value required to support leap seconds)
'L' 三位数表示的毫秒格式,也就是:000-999
'N' 九位数表示的纳秒格式,也就是:000000000-999999999
'p' 与区域(Locale)相关的上下午标志,如:am/pm
'z' RFC 822 样式时差设置,如:-0800
'Z' 表示时区的字符串,代替默认时区
's' 从1 January 1970 00:00:00 UTC到现在秒数
'Q' 从1 January 1970 00:00:00 UTC到现在的毫秒数

5.2 日期转换字符

'B' 区域相关的月分名称,如:"January", "February".
'b' 区域相关的月分名称缩写,如:"Jan", "Feb".
'h' 同'b'
'A' 区域相关的星期几,如:"Sunday", "Monday"
'a' 区域相关的星期几缩写,如:"Sun", "Mon"
'C' 两位表示四位年数除以100的值,也就是:00-99
'Y' 至少四位数字表示的年份
'y' 两位数字表示的年份,也就是:00-99
'j' 一年中的第几天,也就是:001-366
'm' 两位数字表示的月份,也就是:01-12
'd' 两位数字表示的该月第几天,也就是:01-31
'e' 该月第几天,也就是:1-31

5.3 日期与时间通用转移字符

'R' 时间格式化为24小时制,"%tH:%tM"
'T' 时间格式化为24小时制,"%tH:%tM:%tS"
'r' 时间格式化为12小时制,"%tI:%tM:%tS %Tp"
'D' 日期格式化为"%tm/%td/%ty"
'F' ISO 8601完整日期格式为"%tY-%tm-%td"
'c' 日期时间格式为"%ta %tb %td %tT %tZ %tY",如:"Sun Jul 20 16:17:00 EDT 1969"

所有在上述日期与时间转换字符中未显式定义为转换字符的字符都将被视为非法字符,被予以保留,以供扩展使用。

三. 示范代码

System.out.format,System.err.printf,String.format都是通用Formatter实现的。

package com.clzhang.sample.thinking;

import java.io.*;
import java.util.*;
import static java.util.Calendar.*; import org.junit.Test; // System.out.format,System.err.printf,String.format都是通用Formatter实现的。
public class JDK15Formatter {
@Test
public void testFormatter() {
Formatter formatter = new Formatter(System.out); // 倒序输出各参数
// %4$表示参数位置;2表示宽度;s表示toString输出。
formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d");
System.out.println();
// -> " d c b a" // 可选区域参数作为第一个参数,可以用来格式化区域相关的格式数字;precision与width参数用来取整与对齐值。
// Locale.CHINA为区域参数;%参数;+表示结果总包括一个符号;10表示宽度(不够补空格);.4表示小数点后位数;f表示结果被格式化为十进制数
formatter.format(Locale.CHINA, "e = %+10.4f", Math.E);
System.out.println();
// -> "e = +2,7183" // '('数值符号可以用来代替负数符号'-',组分隔符自动插入。
// %参数;(表示圆括号括起来的是负数;,组分隔符;.2表示小数点后保留两位;f表示结果被格式化为十进制数
double balanceDelta = -6217.58231;
formatter.format("Amount gained or lost since last statement: $ %(,.2f", balanceDelta);
System.out.println();
// -> "Amount gained or lost since last statement: $ (6,217.58)" // Writes a formatted string to System.out.
System.out.format("Local time: %tT", Calendar.getInstance());
System.out.println();
// -> Local time: 14:38:39 // Writes formatted output to System.err.
String filename = "C:\\notexists\\food.txt";
File file = new File(filename);
try {
if(!file.exists())
throw new IOException("文件不存在!");
} catch (Exception e) {
System.err.printf("Unable to open file '%1$s': %2$s", filename, e.getMessage());
System.err.println();
// -> Unable to open file 'C:\notexists\food.txt': 文件不存在!
} // Format a string containing a date.
Calendar c = new GregorianCalendar(1995, MAY, 23);
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
System.out.println(s);
// -> Duke's Birthday: 05 23,1995 formatter.close();
}
}

JDK1.5新特性,基础类库篇,格式化类(Formatter)用法的更多相关文章

  1. JDK1.5新特性,语言篇

    Java 1.5版本,就是Java 2 Standard Edition 5,Version 1.5,简称Java 5.版本代号Tiger. 一. 泛型(Generics) C++通过模板技术可以指定 ...

  2. JDK1.7新特性,语言篇

    1. 可以用二进制表达数字 可以用二进制表达数字(加前缀0b/0B),包括:byte, short, int, long // 可以用二进制表达数字(加前缀0b/0B),包括:byte, short, ...

  3. JDK1.5新特性,基础类库篇,集合框架(Collections)

    集合框架在JDK1.5中增强特性如下: 一. 新语言特性的增强 泛型(Generics)- 增加了集合框架在编译时段的元素类型检查,节省了遍历元素时类型转换代码量. For-Loop循环(Enhanc ...

  4. jdk1.6新特性

    1.Web服务元数据 Java 里的Web服务元数据跟微软的方案基本没有语义上的区别,自从JDK5添加了元数据功能(Annotation)之后,SUN几乎重构了整个J2EE体 系, 由于变化很大,干脆 ...

  5. Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27

    Atitit.编程语言新特性 通过类库框架模式增强 提升草案 v3 q27 1. 修改历史2 2. 适用语言::几乎所有编程语言.语言提升的三个渠道::语法,类库,框架,ide2 2.1. 单根继承  ...

  6. JDK1.8新特性——Collector接口和Collectors工具类

    JDK1.8新特性——Collector接口和Collectors工具类 摘要:本文主要学习了在Java1.8中新增的Collector接口和Collectors工具类,以及使用它们在处理集合时的改进 ...

  7. JDK1.8新特性——Stream API

    JDK1.8新特性——Stream API 摘要:本文主要学习了JDK1.8的新特性中有关Stream API的使用. 部分内容来自以下博客: https://blog.csdn.net/icarus ...

  8. JDK1.8新特性(一) ----Lambda表达式、Stream API、函数式接口、方法引用

    jdk1.8新特性知识点: Lambda表达式 Stream API 函数式接口 方法引用和构造器调用 接口中的默认方法和静态方法 新时间日期API default   Lambda表达式     L ...

  9. JDK1.8新特性之(三)--函数式接口

    在上一篇文章中我们介绍了JDK1.8的新特性有以下几项. 1.Lambda表达式 2.方法引用 3.函数式接口 4.默认方法 5.Stream 6.Optional类 7.Nashorm javasc ...

  10. JDK1.8新特性之(一)--Lambda表达式

    近期由于新冠疫情的原因,不能出去游玩,只能在家呆着.于是闲来无事,开始阅读JDK1.8的源代码.在开始之前也查询了以下JDK1.8的新特性,有针对性的开始了这段旅程. 只看不操作,也是不能心领神会的. ...

随机推荐

  1. C# ftp ListFilesOnServer

    public static bool ListFilesOnServer(Uri serverUri) { // The serverUri should start with the ftp:// ...

  2. 1. Change the emulator screen size

    1. "Windows" ==> "Android Virtual Device Manager" ==> Select one emulator ...

  3. 从Date类型字段获得当日周几的DAYNAME函数

    例: select dayname(date) from pos.daywork

  4. Winform控件之DataGridView数据控件显示问题

    近期在做同类的信息记录管理系统时遇到了DataGridView数据控件的显示问题.可能是2015年的上半年没有深入 学习C#开发的原因.这几天又一次搬出来开发,首先遇到的问题就是动态绑定数据显示的问题 ...

  5. 使用mysql 统计函数 结果为null时返回值改为0

    SELECT COALESCE(SUM(total),0)  FROM test_table

  6. ZH奶酪:Windows7+VirtualBox安装Ubuntu虚拟机问题总结

    1.下载VirtualBox(我的是4.3.26版本) https://www.virtualbox.org/ 2.下载Ubuntu ISO文件(我的是ubuntu-14.04-desktop-amd ...

  7. 解决/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found错误的解决

    原因是没有GLIBCXX_3..15版本,或是更高的版本. 一.查看并下载 32位系统: [root@localhost ~]# strings /usr/lib/libstdc++.so. | gr ...

  8. 腾讯地图api将物理地址转化成坐标

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  9. jquery实现下拉联动

    很多项目用到这个功能,虽然写了不下5次以上了,一直没做过记录,记录一下,下次直接拷贝了,免得还得要重复写浪费时间. 先上HTML代码: 品牌: <select class="sa&qu ...

  10. Jprofiler监控工具(内存泄漏)

    内存泄漏 1.测试代码 /** * JProfiler内存监控例子 * * @author yhye * @2011-11-9上午09:46:06 */ public class JProfilerM ...