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. hadoop2.2.0_hbase0.96_zookeeper3.4.5全分布式安装文档下载

    本文档主要内容有: 1.hadoop 2.2.0 集群安装与部署 2.HBase 0.96 集群安装与部署 3.Zookeeper 3.4.5集群安装部署 备注:安装文档可能有所遗漏,后续将持续更新. ...

  2. 嵌入式web服务器-thttpd

    交叉编译thttpd http://lakie.blog.163.com/blog/static/45185220201162910432330/ thttpd安装与调试 http://blog.cs ...

  3. Java从零开始学十九(异常)

    一.什么是异常 从字面上讲,就是不正常的现实就是异常. 程序中的异常也是要在程序运行中才会偶尔发生.如果程序还没有运行,编译就报错,这种不叫异常,这种叫编译错误,通常是语法上的错误 二.java中异常 ...

  4. JavaScript debugger 语句

    实例 开启 debugger ,代码在执行到第三行前终止. var x = 15 * 5; debugger; document.getElementbyId("demo").in ...

  5. 设计模式之适配器模式(Adapter Pattern)C++实现

    适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁.这样的类型的设计模式属于结构型模式.它结合了两个独立接口的功能. 意图:将一个类的接口转换成客户希望的另外一个接口.适配器 ...

  6. 网路总结01-HTTP协议和NSURLConnection

  7. 谷歌浏览器禁止window.close的问题

    当一个窗口不是通过window.open或者window.showModalDialog打开的时候,调用JS的window.close() 谷歌浏览器会提示如下警告,并拒绝执行 Scripts may ...

  8. Drupal的$messages是怎么显示的?

    Drupal的默认主题bartik会在页面顶部显示系统信息,例如警告.状态等.这个过程是如何实现的? 首先,在bartik目录下找到page.tpl.php,这是bartik主题的页面显示模板.其中有 ...

  9. JavaScript-自制日历控件(只选择年月)

    <style> *{margin: 0px; padding: 0px;} </style> <input type="text" name=&quo ...

  10. 职业-把工作当作职业 or 事业?

    有这么一种说法,工作态度可以分为两种:一种是把工作当作职业,另一种是把工作当成事业.态度折射品质,态度影响成败. 把工作当作一份职业的人,以职业交换薪水,完全是为工作而工作,工作是为了糊口养家,上班是 ...