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. mac苹果ping不通网络

    新买了mac,在安装synergy的时候,我拿我的win当server,mac当client,随后发现,synergy提示连接不到server,ping host 失败, cannot connect ...

  2. System.Windows.Forms.Control : Component, IOleControl, IOleObject, IOleInPlaceObject, IOleInPlaceActiveObject....

    #region 程序集 System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ...

  3. Jacoco 代码覆盖率,监控WEB项目

    转载:https://blog.csdn.net/u010469432/article/details/73283824 jacococ代码覆盖率,以客户端形式直接监控远程代码 使用理解 jacoco ...

  4. SpringMVC上传文件的三种方式(转载)

    直接上代码吧,大伙一看便知 这时:commonsmultipartresolver 的源码,可以研究一下 http://www.verysource.com/code/2337329_1/common ...

  5. 子查询二(在HAVING子句中使用子查询)

    HAVING子句的主要功能是对分组后的数据进行过滤,如果子查询在HAVING中表示要进行分组过滤,一般返回单行单列的数据 示例一.查询部门编号,人数,平均工资,并且要求这些部门的平均工资高于公司的平均 ...

  6. 查找树ADT——二叉查找树

    二叉查找树:对于树中的每个节点X,它的左子数种所有关键字值小于X的关键字,而它的右子树种所有关键字值大于X的关键字值. /* 二叉查找树声明 */ #ifndef _TREE_H struct Tre ...

  7. 在Ubuntu下设置默认编辑器

    在默认情况下,Ubuntu 系统会为用户预设程序.就拿文本编辑器来说吧,Ubuntu 预设的是 Nano,对某些朋友来说,使用 Vim 可能更得心应手些.那么如何更改这些预设的程序呢? 你可以使用 s ...

  8. 动态布局中RadioGroup的RadioButton有时候不相互排斥的原因

    近期在做一个答题类的模块,有单选.简答.调查问卷等,我是用动态布局的方式生成答题项的.在弄单选的时候遇到一个比較奇葩的问题,在代码中生成RadioGroup和RadioButton的时候.会发现不能相 ...

  9. idea 配置多个tomcat

      1.打开设置窗口 File-->Settings 2.启用tomcat 3.run-->edit configuration: 3.点击左上角+号-->找到Tomcat Serv ...

  10. 〖Linux〗Shell脚本修改输出文字颜色

    Shell函数: echocolor(){ color=${} && shift case ${color} in black) echo -e "\e[0;30m${@}\ ...