java.util.Formatter 格式化器

本文深入解析Java SE 7中Formatter类的功能与使用,涵盖printf风格格式化字符串的解释,支持数字、字符串及日期时间数据的格式化,同时提供线程安全性和常见类型的格式化定制。

本文翻译 Java SE 7 API 中的 java.util.Formatter类。

public final class Formatter
	extends Object
	implements Closeable, Flushable

用于printf样式格式字符串的解释器。此类支持布局对齐和对齐,数字、字符串和日期/时间数据的通用格式,以及特定于区域设置的输出。支持常见的Java类型,如byteBigDecimalCalendar。通过Formattable接口为任意用户类型提供有限的格式自定义。

Formatters 对于多线程访问不一定安全。 线程安全是可选的,是此类中方法的用户的责任。

Java语言的格式化打印受C’s printf的启发。 虽然格式字符串与C类似,但已经进行了一些自定义以适应Java语言并利用它的一些功能。 此外,Java格式比C更严格; 例如,如果转换与标志不兼容,则会引发异常。 在C中,不适用的标志会被默默忽略。 因此,格式字符串旨在为C程序员识别,但不一定与C中的那些完全兼容。

预期用法示例:

StringBuilder sb = new StringBuilder();
// 将所有输出发送到Appendable对象sb
Formatter formatter = new Formatter(sb, Locale.US);

// 显式参数索引可用于重新排序输出。
formatter.format("%4$2s %3$2s %2$2s %1$2s", "a", "b", "c", "d")
// -> " d  c  b  a"

// 可选的语言环境作为第一个参数可用于获取特定于语言环境的数字格式。 // 精度和宽度可以给出四舍五入并对齐值。
formatter.format(Locale.FRANCE, "e = %+10.4f", Math.E);
// -> "e =    +2,7183"

// '(' 数字标记可用于格式化带括号的负数而不是减号。
// 组分隔符会自动插入。
formatter.format("Amount gained or lost since last statement: $ %(,.2f",
                    balanceDelta);
// -> "Amount gained or lost since last statement: $ (6,217.58)"

存在常见格式化请求的便捷方法,如以下调用所示:

// 将格式化的字符串写入System.out。
System.out.format("Local time: %tT", Calendar.getInstance());
// -> "Local time: 13:34:18"

// 将格式化输出写入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格式化字符串:

//格式化包含日期的字符串。
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"

组织

该规范分为两部分。 第一部分摘要介绍了基本的格式化概念。 本节适用于希望快速入门并熟悉其他编程语言的格式化打印的用户。 第二部分,细节,涵盖了具体的实现细节。 它适用于需要更精确的格式化行为规范的用户。

摘要

本节旨在提供格式化概念的简要概述。 有关精确的行为详细信息,请参阅“详细信息”部分。

格式字符串语法

生成格式化输出的每个方法都需要格式字符串format string和参数列表argument list。格式化字符串是一个String,它可以包含固定文本(fixed text)和一个或多个嵌入式格式化标识符(format specifiers)。请考虑以下示例:

Calendar c = ...;
String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c);

此格式化字符串是format方法的第一个参数。它包含三个格式化标识符%1$tm%1$te%1$tY",用来表示应如何处理参数以及它们应在文本中插入的位置。格式化字符串的其余部分是固定文本,包括Duke's Birthday:和任何其他空格或标点符号(punctuation)。参数列表包含在格式化字符串之后传递给方法的所有参数。在上面的示例中,参数列表的大小为1,由Calendar对象c组成。

  • 常规格式标识符,字符,和数字类型,具有以下语法:
    %[argument_index$][flags][width][.precision]conversion
    可选的argument_index是十进制整数,表示参数列表中参数的位置。第一个参数由1$引用,第二个参数由2$引用,等等。
    可选flags是一组修改输出格式的字符。有效flags集取决于conversion
    可选width是一个非负十进制整数,宽度,表示要写入输出的最小字符数。
    可选precision是一个非负十进制整数,精度,通常用于限制字符数。具体行为取决于conversion
    必选的conversion是一个字符,转换,指示如何格式化参数。给定参数的有效conversion集取决于参数的数据类型。

  • 用于表示日期和时间的类型的格式标识符,具有以下语法:
    %[argument_index$][flags][width]conversion
    可选的argument_indexflagswidth定义如上。
    必选的conversion是两个字符的序列。第一个字符是tT。第二个字符表示要使用的格式。这些字符与GNU date和POSIX strftime(3c)定义的字符类似,但不完全相同。

  • 与参数不对应的格式标识符,具有以下语法:
    %[flags][width]conversion
    可选的argument_indexwidth定义如上。
    必选的conversion是一个字符,指示要在输出中插入的内容。

转换

Conversions分为以下几类:

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

下表总结了支持的转换。 由大写字母表示的转换 (i.e. ‘B’, ‘H’, ‘S’, ‘C’, ‘X’, ‘E’, ‘G’, ‘A’, and ‘T’),与对应的小写转换字符表示的转换相同,除了根据主要区域设置的规则将结果转换为大写。结果相当于String.toUpperCase()的以下调用

out.toUpperCase()
转换参数类别描述
'b', 'B'general如果参数 argnull,则结果为 “false”。 如果argbooleanBoolean,则结果是String.valueOf(arg)返回的字符串。 否则,结果为"true"。
'h', 'H'general如果参数 argnull,则结果为 “null”。否则,通过调用 Integer.toHexString(arg.hashCode()) 来获取结果。
's', 'S'general如果参数argnull,则结果为 “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日期和时间转换字符的前缀。请查阅 Date/Time Conversions.
'%'percent结果是一个字面量 '%' ('\u0025')
'n'line separator结果是特定于平台的行分隔符

任何未明确定义为转换的字符都是非法的,并且保留用于将来的扩展。

Date/Time 转换

tT转换定义了以下日期和时间转换后缀字符。 这些类型与GNU date和POSIX strftime(3c)定义的类型相似但不完全相同。 提供了额外的转换类型来访问特定于Java的功能(例如,L表示秒内的毫秒数)。

以下转换字符用于格式化时间:
‘H’ 24小时制的一天中的小时,格式为两位数,必要时前导零 i.e. 00 - 23.
‘I’ 12小时制的小时,格式化为两位数,必要时带有前导零, i.e. 01 - 12.
‘k’ 24小时制的一天中的小时, i.e. 0 - 23.
‘l’ 12小时制的小时,i.e. 1 - 12.
‘M’ 在一小时内分钟格式化为两位数,前导零必需,i.e. 00 - 59.
‘S’ 分钟内的秒数,格式化为两位数,必要时带有前导零, i.e. 00 - 60 (“60” 是支持闰秒所需的特殊值).
‘L’ 毫秒内的第二个格式为三位数,必要时带有零, i.e. 000 - 999.
‘N’ 在秒内的纳秒,格式化为九位数,必要时带有leadingzeros,i.e. 000000000 - 999999999.
‘p’ 特定于区域的早晨或下午标记为小写,例如“am”或“pm”。 使用转换前缀“TO”会强制此输出为大写。
‘z’ RFC 822样式数字时区偏离GMT,例如-0800。 此值将根据夏令时的需要进行调整。 对于long,Long和Date,使用的时区是此Java虚拟机实例的默认时区。
‘Z’ 表示时区缩写的字符串。 此值将根据夏令时的需要进行调整。 对于long,Long和Date,使用的时区是此Java虚拟机实例的默认时区。 Formatter的语言环境将取代参数的语言环境(如果有的话)。
‘s’ 自1970年1月1日00:00:00 UTC开始以来的秒数, i.e. Long.MIN_VALUE/1000 to Long.MAX_VALUE/1000.
‘Q’ 从1970年1月1日00:00:00 UTC开始的纪元开始以来的毫秒数, i.e. Long.MIN_VALUE to Long.MAX_VALUE.

以下转换字符用于格式化日期:
‘B’ Locale-specific full month name, e.g. “January”, “February”.
‘b’ Locale-specific abbreviated month name,e.g. “Jan”, “Feb”.
‘h’ Same as ‘b’.
‘A’ Locale-specific full name of the day of the week,e.g. “Sunday”, “Monday”
‘a’ Locale-specific short name of the day of the week,e.g. “Sun”, “Mon”
‘C’ Four-digit year divided by 100, formatted as two digits with leading zero as necessary, i.e. 00 - 99
‘Y’ Year, formatted as at least four digits with leading zeros asnecessary, e.g. 0092 equals 92 CE for the Gregoriancalendar.
‘y’ Last two digits of the year, formatted with leading zeros asnecessary, i.e. 00 - 99.
‘j’ Day of year, formatted as three digits with leading zeros asnecessary, e.g. 001 - 366 for the Gregorian calendar.
‘m’ Month, formatted as two digits with leading zeros as necessary,i.e. 01 - 13.
‘d’ Day of month, formatted as two digits with leading zeros asnecessary, i.e. 01 - 31
‘e’ Day of month, formatted as two digits, i.e. 1 - 31.

以下转换字符用于格式化常见日期/时间组合。
‘R’ Time formatted for the 24-hour clock as “%tH:%tM”
‘T’ Time formatted for the 24-hour clock as “%tH:%tM:%tS”.
‘r’ Time formatted for the 12-hour clock as “%tI:%tM:%tS %Tp”.The location of the morning or afternoon marker (’%Tp’) may belocale-dependent.
‘D’ Date formatted as “%tm/%td/%ty”.
‘F’ ISO 8601complete date formatted as “%tY-%tm-%td”.
‘c’ Date and time formatted as “%ta %tb %td %tT %tZ %tY”,e.g. “Sun Jul 20 16:17:00 EDT 1969”.

未明确定义为日期/时间转换后缀的任何字符都是非法的,并保留用于将来的扩展。

Flags 标志

下表总结了支持的标志。 y表示指示的参数类型支持标志。

FlagGeneralCharacterIntegralFloating PointDate/TimeDescription
‘-’yyyyyThe result will be left-justified.
‘#’y1-y3y-The result should use a conversion-dependent alternate form
‘+’--y4y-The result will always include a sign
’ ’--y4y-The result will include a leading space for positive values
‘0’--yy-The result will be zero-padded
‘,’--y2y5-The result will include locale-specific grouping separators
‘(’--y4y5-The result will enclose negative numbers in parentheses

任何未明确定义为标志的字符都是非法的,并保留用于将来的扩展。

宽度

The width is the minimum number of characters to be written to theoutput. For the line separator conversion, width is not applicable; if itis provided, an exception will be thrown.

精度

For general argument types, the precision is the maximum number ofcharacters to be written to the output.

For the floating-point conversions ‘e’, ‘E’, and ‘f’ the precision is the number of digits after the decimalseparator. If the conversion is ‘g’ or ‘G’, then theprecision is the total number of digits in the resulting magnitude afterrounding. If the conversion is ‘a’ or ‘A’, then theprecision must not be specified.

For character, integral, and date/time argument types and the percentand line separator conversions, the precision is not applicable; if aprecision is provided, an exception will be thrown.

参数索引

The argument index is a decimal integer indicating the position of theargument in the argument list. The first argument is referenced by"1 " , t h e s e c o n d b y " 2 ", the second by "2 ",thesecondby"2", etc.

Another way to reference arguments by position is to use the ‘<’ (’\u003c’) flag, which causes the argument forthe previous format specifier to be re-used. For example, the following twostatements would produce identical strings:

Calendar c = …;
String s1 = String.format(“Duke’s Birthday: %1 t m tm %1 tmte,%1$tY”, c);

String s2 = String.format(“Duke’s Birthday: %1$tm %<te,%<tY”, c);


其它后续翻译,待补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值