Java学习笔记之Formatter的用法详解(输出格式化)
java.util.Formatter (摘自sun主页)
printf 风格的格式字符串的解释程序。此类提供了对布局对齐和排列的支持,以及对数值、字符串和日期/时间数据的常规格式和特定于语言环境的输出的支持。支持诸如 byte、BigDecimal
和 Calendar
等常见 Java 类型。任意用户类型的受限格式化定制都是通过 Formattable
接口提供的。
Formatter 对于多线程访问而言没必要是安全的。线程安全是可选的,它对此类中的方法用户负责。
Java 语言的格式化输出在很大程度上受到 C 语言 printf的启发。虽然一些格式字符串与 C 类似,但已进行了某些定制,以适应 Java 语言,并且利用了其中一些特性。此外,Java 的格式比 C 的格式更严格;例如,如果转换与标志不兼容,则会抛出异常。在 C 中,不适用的标志会被忽略。这样,便于 C 程序员识别这些格式字符串,而又不必与 C 中的那些标志完全兼容。
所期望用法的示例:
StringBuilder sb = new StringBuilder(); // Send all output to the Appendable object sb Formatter formatter = new Formatter(sb, Locale.US); // Explicit argument indices may be used to re-order output. formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d") // -> " d c b a" // Optional locale as the first argument can be used to get // locale-specific formatting of numbers. The precision and width can be // given to round and align the value. formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E); // -> "e = +2,7183" // The '(' numeric flag may be used to format negative numbers with // parentheses rather than a minus sign. Group separators are // automatically inserted. formatter.format("Amount gained or lost since last statement: $ %(,.2f", balanceDelta); // -> "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()); // -> "Local time: 13:34:18" // Writes formatted output to System.err. System.err.printf("Unable to open file '%1$s': %2$s", fileName, exception.getMessage()); // -> "Unable to open file 'food': No such file or directory"
与 C 语言的 sprintf(3) 类似,可以使用静态方法 String#format(String,Object...)String.format
来格式化 Strings:
// Format a string containing a date. import java.util.Calendar; import java.util.GregorianCalendar; import static java.util.Calendar.*; Calendar c = new GregorianCalendar(1995, MAY, 23); String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c); // -> s == "Duke's Birthday: May 23, 1995"
结构
此规范分为两部分。第一部分是摘要,包括基本的格式概念。这一部分是为那些想要快速入门并熟悉其他编程语言的格式化输出的用户准备的。第二部分是详细信息,包括具体的实现细节。它是为那些需要更精确格式化行为规范的用户准备的。
摘要
这一部分将提供对格式概念的简单概述。有关精确的行为细节,请参阅详细信息部分。
格式字符串语法
产生格式化输出的每个方法都需要格式字符串 和参数列表。格式字符串是一个 String
,它可以包含固定文本以及一个或多个嵌入的格式说明符。请考虑以下示例:
Calendar c = ...; String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);
此格式字符串是 format 方法的第一个参数。它包含三个格式说明符 "%1$tm"、"%1$te" 和 "%1$tY",它们指出应该如何处理参数以及在文本的什么地方插入它们。格式字符串的其余部分是包括 "Dukes Birthday: " 和其他任何空格或标点符号的固定文本。 参数列表由传递给位于格式字符串之后的方法的所有参数组成。在上述示例中,参数列表的大小为 1,由对象 Calendar
c组成。
- 常规类型、字符类型和数值类型的格式说明符的语法如下:
%[argument_index$][flags][width][.precision]conversion
可选的 argument_index 是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$" 引用,第二个参数由 "2$" 引用,依此类推。
可选 flags是修改输出格式的字符集。有效标志集取决于转换类型。
可选 width是一个非负十进制整数,表明要向输出中写入的最少字符数。
可选 precision是一个非负十进制整数,通常用来限制字符数。特定行为取决于转换类型。
所需 conversion是一个表明应该如何格式化参数的字符。给定参数的有效转换集取决于参数的数据类型。
- 用来表示日期和时间类型的格式说明符的语法如下:
%[argument_index$][flags][width]conversion
可选的 argument_index、flags 和 width的定义同上。
所需的 conversion 是一个由两字符组成的序列。第一个字符是 't' 或 'T'。第二个字符表明所使用的格式。这些字符类似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c)定义的字符。
- 与参数不对应的格式说明符的语法如下:
%[flags][width]conversion
可选 flags 和 width的定义同上。
所需的 conversion 是一个表明要在输出中所插内容的字符。
转换
转换可分为以下几类:
- 常规- 可应用于任何参数类型
- 字符 - 可应用于表示 Unicode 字符的基本类型:char、
Character
、byte、Byte
、short 和Short
。当Character#isValidCodePoint
返回 true 时,可将此转换应用于 int 和Integer
类型 - 数值
- 整数 - 可应用于 Java 的整数类型:byte、
Byte
、short、Short
、int、Integer
、long、Long
和BigInteger
- 浮点 - 可用于 Java 的浮点类型:float、
Float
、double、Double
和BigDecimal
- 整数 - 可应用于 Java 的整数类型:byte、
- 日期/时间 - 可应用于 Java 的、能够对日期或时间进行编码的类型:long、
Long
、Calendar
和Date
。 - 百分比 - 产生字面值 '%' ('%')
- 行分隔符 - 产生特定于平台的行分隔符
下表总结了受支持的转换。由大写字符(如 'B'、'H'、'S'、'C'、'X'、'E'、'G'、'A' 和 'T')表示的转换与由相应的小写字符的转换等同,根据流行的 Locale
规则将结果转换为大写形式除外。后者等同于 String#toUpperCase()
的以下调用
out.toUpperCase()
转换参数类别说明'b', 'B'常规如果参数 arg 为 null,则结果为 "false"。如果 arg 是一个 boolean 值或 Boolean ,则结果为 String.valueOf() 返回的字符串。否则结果为 "true"。'h', 'H'常规如果参数 arg 为 null,则结果为 "null"。否则,结果为调用 Integer.toHexString(arg.hashCode())得到的结果。's', 'S'常规如果参数 arg 为 null,则结果为 "null"。如果 arg 实现 Formattable ,则调用 arg.formatTo 。否则,结果为调用 arg.toString()得到的结果。'c', 'C'字符结果是一个 Unicode 字符'd'整数结果被格式化为十进制整数'o'整数结果被格式化为八进制整数'x', 'X'整数结果被格式化为十六进制整数'e', 'E'浮点结果被格式化为用计算机科学记数法表示的十进制数'f'浮点结果被格式化为十进制数'g', 'G'浮点根据精度和舍入运算后的值,使用计算机科学记数形式或十进制格式对结果进行格式化。'a', 'A'浮点结果被格式化为带有效位数和指数的十六进制浮点数't', 'T'日期/时间日期和时间转换字符的前缀。请参阅日期/时间转换。'%'百分比结果为字面值 '%' ('%')'n'行分隔符结果为特定于平台的行分隔符 |
---|
任何未明确定义为转换的字符都是非法字符,并且都被保留,以供将来扩展使用。
日期/时间转换
以下日期和时间转换的后缀字符是为 't' 和 'T' 转换定义的。这些类型相似于但不完全等同于那些由 GNU date 和 POSIX strftime(3c) 定义的类型。提供其他转换类型是为了访问特定于 Java 的功能(如将 'L'用作秒中的毫秒)。
以下转换字符用来格式化时间:
'H'24 小时制的小时,被格式化为必要时带前导零的两位数,即 00 - 23。'I'12 小时制的小时,被格式化为必要时带前导零的两位数,即 01 - 12。'k'24 小时制的小时,即 0 - 23。'l'12 小时制的小时,即 1 - 12。'M'小时中的分钟,被格式化为必要时带前导零的两位数,即 00 - 59。'S'分钟中的秒,被格式化为必要时带前导零的两位数,即 00 - 60 ("60" 是支持闰秒所需的一个特殊值)。'L'秒中的毫秒,被格式化为必要时带前导零的三位数,即 000 - 999。'N'秒中的毫微秒,被格式化为必要时带前导零的九位数,即 000000000 - 999999999。'p'特定于语言环境的 上午或下午 标记以小写形式表示,例如 "am" 或 "pm"。使用转换前缀 'T'可以强行将此输出转换为大写形式。'z'相对于 GMT 的 RFC 822 格式的数字时区偏移量,例如 -0800。'Z'表示时区缩写形式的字符串。Formatter 的语言环境将取代参数的语言环境(如果有)。's'自协调世界时 (UTC) 1970 年 1 月 1 日 00:00:00 至现在所经过的秒数,即 Long.MIN_VALUE/1000 与 Long.MAX_VALUE/1000之间的差值。'Q'自协调世界时 (UTC) 1970 年 1 月 1 日 00:00:00 至现在所经过的毫秒数,即 Long.MIN_VALUE 与 Long.MAX_VALUE 之间的差值。 |
以下转换字符用来格式化日期:
'B'特定于语言环境的月份全称,例如 "January" 和 "February"。'b'特定于语言环境的月份简称,例如 "Jan" 和 "Feb"。'h'与 'b'相同。'A'特定于语言环境的星期几全称,例如 "Sunday" 和 "Monday"'a'特定于语言环境的星期几简称,例如 "Sun" 和 "Mon"'C'除以 100 的四位数表示的年份,被格式化为必要时带前导零的两位数,即 00 - 99'Y'年份,被格式化为必要时带前导零的四位数(至少),例如,0092 等于格里高利历的 92CE。'y'年份的最后两位数,被格式化为必要时带前导零的两位数,即 00 - 99。'j'一年中的天数,被格式化为必要时带前导零的三位数,例如,对于格里高利历是 001 - 366。'm'月份,被格式化为必要时带前导零的两位数,即 01 - 13。'd'一个月中的天数,被格式化为必要时带前导零两位数,即 01 - 31'e'一个月中的天数,被格式化为两位数,即 1 - 31。 |
以下转换字符用于格式化常见的日期/时间组合。
'R'24 小时制的时间,被格式化为 "%tH:%tM"'T'24 小时制的时间,被格式化为 "%tH:%tM:%tS"。'r'12 小时制的时间,被格式化为 "%tI:%tM:%tS %Tp"。上午或下午标记 ('%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"。 |
任何未明确定义为转换的字符都是非法字符,并且都被保留,以供将来扩展使用。
标志
下表总结了受支持的标志。y表示该标志受指示参数类型支持。
标志常规字符整数浮点日期/时间说明'-'yyyyy结果将是左对齐的。'#'y1-y3y-结果应该使用依赖于转换类型的替换形式'+'--y4y-结果总是包括一个符号' '--y4y-对于正值,结果中将包括一个前导空格'0'--yy-结果将用零来填充','--y2y5-结果将包括特定于语言环境的组分隔符'('--y4y5-结果将是用圆括号括起来的负数 |
---|
1 取决于 Formattable
的定义。
2 只适用于 'd'转换。
3 只适用于 'o'、'x' 和 'X'转换。
4 对 BigInteger
应用 'd'、'o'、'x' 和 'X' 转换时,或者对 byte 及 Byte
、short 及 Short
、int 及 Integer
、long 及 Long
分别应用 'd'转换时适用。
5 只适用于 'e'、'E'、'f'、'g' 和 'G'转换。
任何未显式定义为标志的字符都是非法字符,并且都被保留,以供扩展使用。
宽度
宽度是将向输出中写入的最少字符数。对于行分隔符转换,不适用宽度,如果提供宽度,则会抛出异常。
精度
对于常规参数类型,精度是将向输出中写入的最多字符数。
对于浮点转换 'e'、'E' 和 'f',精度是小数点分隔符后的位数。如果转换是 'g' 或 'G',那么精度是舍入计算后所得数值的所有位数。如果转换是 'a' 或 'A',则不必指定精度。
对于字符、整数和日期/时间参数类型转换,以及百分比和行分隔符转换,精度是不适用的;如果提供精度,则会抛出异常。
参数索引
参数索引是一个十进制整数,用于表明参数在参数列表中的位置。第一个参数由 "1$" 引用,第二个参数由 "2$" 引用,依此类推。
根据位置引用参数的另一种方法是使用 '<' ('<') 标志,这将会重用以前格式说明符的参数。例如,以下两条语句产生的字符相同:
Calendar c = ...; String s1 = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c); String s2 = String.format("Duke's Birthday: %1$tm %<te,%<tY", c);
详细信息
这一部分将提供格式化行为规范方面的细节,其中包括条件和异常、受支持的数据类型、本地化以及标志、转换和数据类型之间的交互。有关格式化概念的概述,请参阅摘要。
任何未明确定义为转换、日期/时间转换前缀或标志的字符都是非法字符,并且这些字符都被保留,以供未来扩展使用。在格式字符串中使用这样的字符会导致抛出 UnknownFormatConversionException
或 UnknownFormatFlagsException
。
如果格式说明符包含带有无效值或不受支持的其他值的宽度或精度,则将分别抛出 IllegalFormatWidthException
或 IllegalFormatPrecisionException
。
如果格式说明符包含不适用于对应参数的转换字符,则将抛出 IllegalFormatConversionException
。
所有指定异常都可能被 Formatter 的任何 format 方法以及任何 format 的便捷方法抛出,比如 String#format(String,Object...)String.format
和 java.io.PrintStream#printf(String,Object...)PrintStream.printf
。 String.format} and PrintStream.printf
.
由大写字符(如 'B'、'H'、'S'、'C'、'X'、'E'、'G'、'A' 和 'T')表示的转换与那些相应的小写字符表示的转换相同,根据流行的 Locale
规则将结果转换成大写形式除外。结果等同于 String#toUpperCase()
的以下调用
out.toUpperCase()
常规
以下常规转换可应用于任何参数类型:
'b''b'将生成 "true" 或 "false",由 Boolean#toString(boolean) 返回。
如果参数为 null,则结果为 "false"。如果参数是一个 boolean 值或 如果给出 '#' 标志,则将抛出 如果参数 arg 为 null,则结果为 "null"。否则,结果为调用 Integer.toHexString(arg.hashCode())得到的结果。 如果给出 '#' 标志,则将抛出 如果参数为 null,则结果为 "null"。如果参数实现了 如果给出 '#' 标志,且参数不是 |
'-''-'将输出左对齐。根据需要在转换值结尾处添加空格 (' '),以满足字段的最小宽度要求。如果没有提供宽度,则将抛出 MissingFormatWidthException 。如果没有给出此标志,则输出将是右对齐的。'#''#'要求输出使用替换形式。此形式的定义通过转换指定。 |
宽度 是将向输出中写入的最少字符数。如果转换值的长度小于宽度,则用 ' ' (\u0020') 填充输出,直到字符总数等于宽度为止。默认情况下,是在左边进行填充。如果给出 '-'标志,则在右边进行填充。如果没有指定宽度,则没有最小宽度。
精度是将向输出中写入的最多字符数。精度的应用要先于宽度,因此,即使宽度大于精度,输出也将被截取为 precision字符。如果没有指定精度,则对字符数没有明确限制。
字符
此转换可应用于 char 和 Character
。它还可应用于类型 byte、Byte
、short 和 Short
、 int 和 Integer
。当 Character#isValidCodePoint
返回 true 时,此转换也可应用于 int 和 Integer
。如果返回 false,则将抛出 IllegalFormatCodePointException
。
'c''c'将参数格式化为 Unicode Character Representation 中描述的 Unicode 字符。在该参数表示增补字符的情况下,它可能是多个 16 位 char。
如果给出 '#' 标志,则将抛出 |
'-' 标志是为应用常规转换而定义的。如果给出 '#' 标志,则将抛出 FormatFlagsConversionMismatchException
。
宽度是为了实现常规转换而定义的。
精度不适用。如果指定精度,则将抛出 IllegalFormatPrecisionException
。
数值
数值转换分为以下几类:
将根据以下算法对数值类型进行格式化:
在获得数字的整数部分、小数部分和指数(适用于数据类型)之后,将应用以下转换:
- 将字符串中的每个数字字符 d 都替换为特定于语言环境的数字,该数字是相对于当前语言环境的零数字 z 来计算的;即 d - '0' + z。
- 如果存在小数点分隔符,则用特定于语言环境的小数点分隔符替换。
- 如果给出 ',' (',') flag 标志,则插入特定于语言环境的组分隔符,这是通过从最低位到最高位浏览字符串的整数部分并不时插入该语言环境组大小定义的分隔符来实现的。
- 如果给出 '0' 标志,则在符号字符(如果有的话)之后、第一个非零数字前插入特定于语言环境的零数字,直到字符串长度等于所要求的字段宽度。
- 如果该值为负,并且给出了 '(' 标志,那么预先考虑 '(' ('('),并追加一个 ')' (')')。
- 如果该值为负(或者为浮点负零),并且没有给出 '(' 标志,那么预先考虑 '-' ('-')。
- 如果给出 '+' 标志,并且该值为正或零(或者为浮点正零),那么将预先考虑 '+' ('+')。
如果该值为 NaN 或正无穷大,则分别输出文本字符串 "NaN" 或 "Infinity"。如果该值为负无穷大,那么输出将是 "(Infinity)";否则如果给出 '('标志,那么输出将是 "-Infinity"。这些值都没有被本地化。
以下转换可应用于 byte、Byte
、short、Short
、int、Integer
、long 和 Long
。
'd''T'将参数格式化为十进制整数。应用本地化算法。
如果给出 '0'标志,并且值为负,则在符号后填充零。 如果给出 '#' 标志,则将抛出 如果 x 为负,那么结果将是通过将 2n 添加到值中产生的一个无符号值,其中 n 是在适当时候由类 Byte、Short、Integer 或 Long 中的静态 SIZE字段返回的类型中的位数。 如果给出 '#' 标志,则输出将始终以基数指示符 '0'开始。 如果给出 '0'标志,则使用前导零填充输出,这些零被填充到以下任意指示符号后面的字段宽度中。 如果给出 '('、'+'、' ' 或 '、' 标志,则将抛出 如果 x 为负,那么结果将为把 2n 添加到值中产生的一个无符号值,其中 n 是在适当时候,由类 Byte、Short、Integer 或 Long 中的静态 SIZE字段返回的类型中的位数。 如果给出 '#' 标志,则输出将始终以基数指示符 '0x'开始。 如果给出 '0'标志,则使用前导零填充输出,这些零被填充到基数指示符或符号(如果存在)后面的字段宽度中。 如果给出 '('、' '、'+' 或 '、' 标志,则将抛出 |
如果该转换是 'o'、'x' 或 'X' 转换,并且给出了 '#' 和 '0' 标志,那么结果将包含基数指示符(对于八进制是 '0',对于十六进制是 '0' 或 "0x")、一定数量的零(基于宽度)和该值。
如果没有给出 '-'标志,则在符号前填充空格。
'+''+'要求所有正数的输出都包含一个正号。如果没有给出此标志,则只有负值包含符号。
如果同时给出了 '+' 和 ' ' 标志,则将抛出 如果同时给出了 '+' 和 ' ' 标志,则将抛出 MissingFormatWidthException 。
如果同时给出 '-' 和 '0' 标志,则将抛出 |
- width中的输出是右对齐的
- 负数以 '-' ('-') 开始
- 正数和零不包括符号或额外的前导空格
- 不包括组分隔符
The 宽度 是将向输出中写入的最少字符数。这包括所有符号、数字、组分隔符、基数指示符和圆括号。如果转换值的长度小于宽度,则用空格('\u0020') 填充输出,直到字符总数等于宽度。默认情况下,在左边进行填补。如果给出 '-'标志,则在右边进行填补。如果没有指定宽度,则没有最小宽度。
精度不适用。如果指定精度,则将抛出 IllegalFormatPrecisionException
。
以下转换可应用于 java.math.BigInteger
。
'd''T'要求将输出格式化为十进制整数。应用本地化算法。
如果给出 '#' 标志,则将抛出 如果 x 为负,那么结果将是以 '-' ('\u002d') 开始的有符号值。允许对这种类型使用有符号输出,因为它不同于基本类型,在没有假定显式数据类型大小的情况下,不可能创建无符号的等效值。 如果 x 为正数或零,且给出了 '+' 标志,那么结果是以 '+' ('+') 开始的。 如果给出 '#' 标志,那么输出将始终以 '0'前缀开始。 如果给出 '0'标志,那么将使用前导零填充输出,这些零被填充到指示符后的字段宽度中。 如果给出 ',' 标志,则将抛出 如果 x 为负,那么结果是以 '-' ('_apos;) 开始的有符号值。此类型允许使用有符号输出,因为与基本类型不同,如果不假定明确的数据类型大小,则不可能创建无符号的等效数。 如果 x 为正数或零,且给出了 '+' 标志,那么结果以 '+' ('+') 开始。 如果给出 '#' 标志,那么输出将始终以基数指示符 '0x'开始。 如果给出 '0'标志,那么将使用前导零填充输出,这些零被填充到基数指示符或符号(如果存在)后面的字段宽度中。 如果给出 ',' 标志,则将抛出 |
如果该转换是 'o'、'x' 或 'X',并且给出了 '#' 和 '0' 标志,那么结果将包含基数指示符(对于八进制是 '0',对于十六进制是 '0' 或 "0x")、一定数量的零(基于宽度)和该值。
如果给出 '0'标志,并且值为负,则在符号后填充零。
如果没有给出 '-'标志,则在符号前填充空格。
应用为 Byte、Short、Integer 和 Long 定义的所有标志。没有给出标志时的默认行为与 Byte、Short、Integer 和 Long 的行为相同。
宽度的规范与为 Byte、Short、Integer 和 Long 定义的规范相同。
精度不适用。如果指定精度,则将抛出 IllegalFormatPrecisionException
。
以下转换可应用于 float、Float
、double 和 Double
。
'e''e'要求使用科学记数法来格式化输出。应用本地化算法。
数值 m的格式取决它的值。 如果 m是 NaN 或无穷大,则分别输出文本字符串 "NaN" 或 "Infinity"。这些值都没有被本地化。 如果 m 是正零或负零,则指数将是 "+00"。 否则,结果是表示变量的符号和大小(绝对值)的字符串。符号的格式在本地化算法中已经描述。数值 m的格式取决它的值。 让 n 成为满足 10n <= m < 10n+1 的唯一整数;让 a 成为 m 和 10n 的精确算术商数值,且满足 1 <= a < 10。然后将该数值解释为 a 的整数部分,因为是一个小数位数,所以后面跟着小数点分隔符,再后面是表示 a 的小数部分的小数位数,后跟指数符号 'e' ('e'),这之后是指数符号,后跟十进制整数形式表示的 n,它由方法 在结果中,m 或 a 的小数部分的位数等于精度。如果没有指定精度,则默认值为 6。如果精度小于将出现在分别由 如果给出 ',' 标志,则将抛出 在对精度进行舍入运算后,所得数值 m的格式取决于它的值。 如果 m 大于等于 10-4 但小于 10精度,则以十进制形式表示它。 如果 m 小于 10-4 或者大于等于 10精度,则以计算机科学记数法表示它。 m 中的总有效位数等于其精度。如果没有指定精度,则其默认值为 6。如果精度为 0,则该值将为 1。 如果给出 '#' 标志,则将抛出 结果是表示参数的符号和大小(绝对值)的字符串。符号的格式在本地化算法中已经描述。数值 m的格式取决它的值。 如果 m是 NaN 或无穷大,则将分别输出文本字符串 "NaN" 或 "Infinity"。这些值都没有被本地化。 将数值格式化为 m 的整数部分(不带前导零),后跟小数点分隔符,再后面是表示 m的小数部分的一个或多个十进制数字。 在结果中,m 或 a 的小数部分的位数等于精度。如果没有指定精度,则默认值为 6。如果该精度小于将要出现在分别由 结果是表示参数 x的符号和大小(绝对值)的字符串。 如果 x 为负值或负零值,那么结果将以 '-' ('-') 开始。 如果 x 为正值或正零值,且给出了 '+' 标志,那么结果将以 '+' ('+') 开始。 数值 m的格式取决它的值。
如果给出 '(' 或 ',' 标志,则将抛出 |
应用为 Byte、Short、Integer 和 Long 定义的所有标志。
如果给出 '#'标志,则将始终存在小数点分隔符。
- width中的输出是右对齐的。
- 负数以 '-'开头
- 正数和正零不包括符号或额外的前导空格
- 不包括组分隔符
- 小数点分隔符只在后面有数字时才出现
The 宽度 是将向输出中写入的最少字符数。这包括可应用的所有符号、数字、组分隔符、小数点分隔符、指数符号、基数指示符、圆括号和表示无穷大和 NaN 的字符串。如果转换值的长度小于宽度,则用空格('\u0020') 填充输出,直到字符总数等于宽度。默认情况下,在左边进行填充。如果给出 '-'标志,则在右边进行填充。如果没有指定宽度,则没有最小宽度。
如果 转换 是 'e'、'E' 或 'f',则精度是小数点分隔符后的位数。如果没有指定精度,则假定精度为 6。
如果转换是 'g' 或 'G' 转换,那么精度就是舍入运算后所得数值的总有效位数。如果没有指定精度,则默认值为 6。如果精度为 0,则该值将为 1。
如果转换是 'a' 或 'A' 转换,则精度是小数点分隔符后十六进制数字的位数。如果没有提供精度,则将输出 Double#toHexString(double)
返回的所有数字。
以下转换可应用于 BigDecimal
。
'e''e'要求使用计算机科学记数法对输出进行格式化。应用本地化算法。
数值 m的格式取决于它的值。 如果 m 为正零或负零,则指数将为 "+00"。 否则,结果是表示参数的符号和大小(绝对值)的字符串。符号的格式在本地化算法中已经描述。数值 m的格式取决于它的值。 让 n 成为满足 10n <= m < 10n+1 的唯一整数;让 a 成为 m 和 10n 的精确算术商数值,且满足 1 <= a < 10。然后将该数值解释为 a 的整数部分,因为是一个小数位数,所以后面跟着小数点分隔符,再后面是表示 a 的小数部分的小数位数,后跟指数符号 'e' ('e'),这之后是指数符号,后跟十进制整数形式表示的 n,它由方法 在结果中,m 或 a 的小数部分的位数等于精度。如果没有指定精度,则默认值为 6。如果精度小于将出现在分别由 如果给出 ',' 标志,则将抛出 在对精度进行舍入运算后,所得数值 m的格式取决于它的值。 如果 m 大于等于 10-4 但小于 10精度,则以十进制形式表示它。 如果 m 小于 10-4 或者大于等于 10精度,则以计算机科学记数法表示它。 m 中的总的有效位数等于精度。如果没有指定精度,则默认值为 6。如果精度为 0,则该值将为 1。 如果给出 '#' 标志,则将抛出 结果是表示参数的符号和大小(绝对值)的字符串。符号的格式在本地化算法中已经描述。数值 m的格式取决于它的值。 将该数值格式化为 m 的整数部分(不带前导零),后跟小数点分隔符,再后面是表示 m的小数部分的一个或多个十进制数字。 在结果中,m 或 a 的小数部分的位数等于精度。如果没有指定精度,则默认值为 6。如果精度小于将出现在分别由 |
应用为 Byte、Short、Integer 和 Long 定义的所有标志。
如果给出 '#'标志,则将始终存在小数点分隔符。
没有给出标志时的默认行为与 Float 和 Double 的行为相同。
宽度和精度的规范与为 Float 和 Double 定义的规范相同。
日期/时间
此转换可应用于 long、Long
、Calendar
和 Date
。
't''t'日期和时间转换字符的前缀。'T''T''t' 的大写形式。 |
以下日期和时间转换字符后缀是为 't' 和 'T' 转换定义的。这些类型类似于但不完全等同于 GNU date 和 POSIX strftime(3c) 定义的那些类型。提供其他转换类型是为了访问特定于 Java 的功能(例如,'L'用于秒中的毫秒)。
以下转换字符用来格式化时间:
'H''H'24 小时制的小时,被格式化为必要时带前导零的两位数,即 00 - 23。00对应午夜。'I''I'12 小时制的小时,被格式化为必要时带前导零的两位数,即 01 - 12。01对应于 1 点钟(上午或下午)。'k''k'24 小时制的小时,即 0 - 23。0对应于午夜。'l''l'12 小时制的小时,即 1 - 12。1对应于上午或下午的一点钟。'M''M'小时中的分钟,被格式化为必要时带前导零的两位数,即 00 - 59。'S''S'分钟中的秒,被格式化为必要时带前导零的两位数,即 00 - 60("60" 是支持闰秒所需的一个特殊值)。'L''L'秒中的毫秒,被格式化为必要时带前导零的三位数,即 000 - 999。'N''N'秒中的毫微秒,被格式化为必要时带前导零的九位数,即 000000000 - 999999999。此值的精度受底层操作系统或硬件解析的限制。'p''p'特定于语言环境的上午或下午标记以小写形式表示,例如 "am" 或 "pm"。使用转换前缀 'T' 可以强行将此输出转换为大写形式。(注意,'p' 产生的输出是小写的。而 GNU date 和 POSIX strftime(3c)产生的输出是大写的。)'z''z'相对于 GMT 的 RFC 822 格式的数字时区偏移量,例如 -0800。'Z''Z'表示时区的缩写形式的字符串。's''s'自协调世界时 (UTC) 1970 年 1 月 1 日 00:00:00 至现在所经过的秒数,也就是 Long.MIN_VALUE/1000 与 Long.MAX_VALUE/1000之间的差值。'Q''O'自协调世界时 (UTC) 1970 年 1 月 1 日 00:00:00 至现在所经过的毫秒数,即 Long.MIN_VALUE 与 Long.MAX_VALUE 之间的差值。此值的精度受底层操作系统或硬件解析的限制。 |
以下转换字符用来格式化日期:
'B''B'特定于语言环境的完整月份名称,例如 "January" 和 "February"。'b''b'特定于语言环境的月份简称,例如 "Jan" 和 "Feb"。'h''h'与 'b'相同。'A''A'特定于语言环境的星期几的全称,例如 "Sunday" 和 "Monday"'a''a'特定于语言环境的星期几的简称,例如 "Sun" 和 "Mon"'C''C'除以 100 的四位数表示的年份,被格式化为必要时带前导零的两位数,即 00 - 99'Y''Y'年份,被格式化为必要时带前导零的四位数(至少),例如 0092 等于格里高利历的 92CE。'y''y'年份的最后两位数,被格式化为必要时带前导零的两位数,即 00 - 99。'j''j'一年中的天数,被格式化为必要时带前导零的三位数,例如,对于格里高利历是 001 - 366。001对应于一年中的第一天。'm''m'月份,被格式化为必要时带前导零的两位数,即 01 - 13,其中 "01" 是一年的第一个月,("13" 是支持阴历所需的一个特殊值)。'd''d'一个月中的天数,被格式化为必要时带前导零的两位数,即 01 - 31,其中 "01" 是一个月的第一天。'e''e'一个月中的天数,被格式化为两位数,即 1 - 31,其中 "1" 是一个月中的第一天。 |
以下转换字符用于格式化常见的日期/时间组合。
'R''R'24 小时制的时间,被格式化为 "%tH:%tM"'T''T'24 小时制的时间,被格式化为 "%tH:%tM:%tS"。'r''r'12 小时制的时间,被格式化为 "%tI:%tM:%tS %Tp"。上午或下午标记 ('%Tp') 的位置可能与地区有关。'D''D'日期,被格式化为 "%tm/%td/%ty"。'F''F'ISO 8601 格式的完整日期,被格式化为 "%tY-%tm-%td"。'c''c'日期和时间,被格式化为 "%ta %tb %td %tT %tZ %tY",例如 "Sun Jul 20 16:17:00 EDT 1969"。 |
应用为常规转换而定义的 '-' 标志。如果给出 '#' 标志,则将抛出 FormatFlagsConversionMismatchException
。
宽度 是将向输出中写入的最少字符数。如果转换值的长度小于 width,则用空格(' ') 来填充输出,直到总字符数等于宽度。默认情况下,在左边进行填充。如果给出 '-'标志,则在右边进行填充。如果没有指定宽度,则没有最小宽度。
精度不适用。如果指定了精度,则将抛出 IllegalFormatPrecisionException
。
百分比
该转换不对应于任何参数。
'%'结果是一个字面值 '%' ('%')
宽度 是将向输出中写入的最少字符数,包括 '%'。如果转换值的长度小于 width,则用空格 (' ') 来填充输出,直到总字符数等于宽度。在左边进行填充。如果没有指定宽度,则只输出 '%'。 应用为常规转换而定义的 '-' 标志。如果提供其他任何标志,则将抛出 精度不适用。如果指定精度,则将抛出 |
行分隔符
该转换不对应于任何参数。
'n'由 System.getProperty("line.separator") 返回的特定于平台的行分隔符。 |
标志、宽度和精度都不可用。如果提供这三者,则会分别抛出 IllegalFormatFlagsException
、IllegalFormatWidthException
和 IllegalFormatPrecisionException
。
参数索引
格式说明符可以通过三种方式引用参数:
- 显式索引 是在格式说明符中包含参数索引时使用。参数索引是一个十进制整数,用于指示参数在参数列表中的位置。第一个参数由 "1$" 引用,第二个参数由 "2$" 引用,依此类推。可以多次引用任何一个参数。
例如:
formatter.format("%4$s %3$s %2$s %1$s %4$s %3$s %2$s %1$s", "a", "b", "c", "d") // -> "d c b a d c b a"
- 相对索引 是在格式说明符中包含 '<' ('<') 标志时使用,该标志将导致重用以前格式说明符的参数。如果不存在以前的参数,则抛出
MissingFormatArgumentException
。formatter.format("%s %s %<s %<s", "a", "b", "c", "d") // -> "b a a b" // "c" and "d" are ignored because they are not referenced
- 普通索引 在格式说明符中既不包含参数索引也不包含 '<'标志时使用。每个使用普通索引的格式说明符都分配了一个连续隐式索引,分配在独立于显式索引或相对索引使用的参数列表中。
formatter.format("%s %s %s %s", "a", "b", "c", "d") // -> "a b c d"
可能有一个使用所有索引形式的格式字符串,例如:
formatter.format("%2$s %s %<s %s", "a", "b", "c", "d") // -> "b a a b" // "c" and "d" are ignored because they are not referenced
参数的最大数量受到 Java Machine Specification 定义的 Java 数组 的最大维数的限制。如果参数索引与可用参数不对应,则抛出 MissingFormatArgumentException
。
如果参数多于格式说明符,则忽略额外的参数。
除非另行指定,否则向此类中的任何方法或构造方法传递 null 参数都将抛出 NullPointerException
。
version | 1.26, 06/28/06 |
since | 1.5 |
Constructors | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
public | Formatter() 构造一个新 formatter。 格式化输出的目标文件是 |
||||||||||||
public | Formatter(Appendable a) 构造一个带指定目标文件的新 formatter。 对于 Java 虚拟机的此实例,所使用的语言环境是默认语言环境。
|
||||||||||||
public | Formatter(Locale l) 构造一个带指定语言环境的新 formatter。 格式化输出的目标文件是
|
||||||||||||
public | Formatter(Appendable a, Locale l) 构造一个带指定目标文件和语言环境的新 formatter。
|
||||||||||||
public | Formatter(String fileName) throws FileNotFoundException 构造一个带指定文件名的新 formatter。 对于 Java 虚拟机的此实例,所使用的字符集是默认字符集。 对于 Java 虚拟机的此实例,所使用的语言环境是默认语言环境。
|
||||||||||||
public | Formatter(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException 构造一个带指定文件名和字符集的新 formatter。 对于 Java 虚拟机的此实例,所使用的语言环境是默认语言环境。
|
||||||||||||
public | Formatter(String fileName, String csn, Locale l) throws FileNotFoundException, UnsupportedEncodingException 构造一个带指定文件名、字符集和语言环境的新 formatter。
|
||||||||||||
public | Formatter(File file) throws FileNotFoundException 构造一个带指定文件的新 formatter。 对于 Java 虚拟机的此实例,所使用的字符集是默认字符集。 对于 Java 虚拟机的此实例,所使用的语言环境是默认语言环境。
|
||||||||||||
public | Formatter(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException 构造一个带指定文件和字符集的新 formatter。 对于 Java 虚拟机的此实例,所使用的语言环境是默认语言环境。
|
||||||||||||
public | Formatter(File file, String csn, Locale l) throws FileNotFoundException, UnsupportedEncodingException 构造一个带指定文件、字符集和语言环境的新 formatter。
|
||||||||||||
public | Formatter(PrintStream ps) 构造一个带指定输出流的新 formatter。 对于 Java 虚拟机的此实例,所使用的语言环境是默认语言环境。 将字符写入给定的
|
||||||||||||
public | Formatter(OutputStream os) 构造一个带指定输出流的新 formatter。 对于 Java 虚拟机的此实例,所使用的字符集是默认字符集。 对于 Java 虚拟机的此实例,所使用的语言环境是默认语言环境。
|
||||||||||||
public | Formatter(OutputStream os, String csn) throws UnsupportedEncodingException 构造一个带指定输出流和字符集的新 formatter。 对于 Java 虚拟机的此实例,所使用的语言环境是默认语言环境。
|
||||||||||||
public | Formatter(OutputStream os, String csn, Locale l) throws UnsupportedEncodingException 构造一个带指定输出流、字符集和语言环境的新 formatter。
|
Methods | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
public void | close() 关闭此 formatter。如果目标文件实现 java.io.Closeable 接口,则调用其 close方法。
关闭 formatter 允许释放它可能保持(比如打开文件)的资源。如果已经关闭 formatter,则调用此方法无效。 如果试图在此 formatter 已经关闭之后调用其中除 |
||||||||||||
public void | flush() 刷新此 formatter。如果目标文件实现 java.io.Flushable 接口,则调用其 flush方法。
刷新 formatter 会使目标文件中的所有缓冲输出都写入底层流中。
|
||||||||||||
public Formatter | format(String format, Object[] args) 使用指定格式字符串和参数将一个格式化字符串写入此对象的目标文件中。使用的语言环境是构造此 formatter 期间定义的语言环境。
|
||||||||||||
public Formatter | format(Locale l, String format, Object[] args) 使用指定的语言环境、格式字符串和参数,将一个格式化字符串写入此对象的目标文件中。
|
||||||||||||
public IOException | ioException() 返回由此 formatter 的 Appendable 方法上次抛出的 IOException异常。
如果目标文件的 append() 方法从未抛出 IOException,则此方法将始终返回 null。
|
||||||||||||
public Locale | locale() 返回构造此 formatter 时设置的语言环境。 此对象的带语言环境参数的
|
||||||||||||
public Appendable | out() 返回输出的目标文件。
|
||||||||||||
public String | toString() 返回对输出的目标文件调用 toString() 的结果。例如,以下代码将文本格式化到 StringBuilder 中,然后获取得到的字符串:
Formatter f = new Formatter(); f.format("Last reboot at %tc", lastRebootDate); String s = f.toString(); // -> s == "Last reboot at Sat Jan 01 00:00:00 PST 2000" 调用此方法的方式与调用 out().toString() 的方式完全相同。 out().toString() 根据针对
|