printf-style的格式化字符串解释器。这个类为布局对齐、数字和字符串和时间数据以及特定区域的输出提供通用格式支持。普遍的java类型 例如byte {@link java.math.BigDecimal BigDecimal}, and {@link Calendar} *是支持的
通过Formattable接口限制任意用户自定义的类型格式。

Formatters 对于多线程访问不一定是安全的。线程*安全是可选的,是这个类中方法的使用者的责任

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的 {@code sprintf(3)}, 字符串可以被格式化 用静态method {@link String#format(String,Object…) String.format}

// 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$tb %1$te, %1$tY", c);
 *   // -> s == "Duke's Birthday: May 23, 1995"
 *

Format String 语法

生成格式化输出的每种方法都需要一个格式字符串和一个参数列表。格式化字符串是
{@link * String}。可以包含固定文本和一个或多个嵌入格式说明符。考虑下面的例子:

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

格式化字符串是format方法的第一个参数
包含三个格式化规范”{@code %1tm}", "{@code %1 tm}", "{@code %1 te}", and * "{@code %1$tY}”
显示参数怎么被处理和 他们应该插入到文本的哪里
剩下的部分格式化字符串是固定的包含 {@code “Dukes Birthday: “} 和任何其他的空格和标点。

参数列表由许多通过方法的参数组成在format字符串后
在上面的例子中 参数列表的大小为1 {@link java.util.Calendar Calendar} 对象组成代码C

特定的规范给通用的 字符和数字类型有下面的语法:

%[argument_index$][flags][width][.precision]conversion

可选参数是一个十进制证书
代表参数列表中参数的位置
第一个参数由{@code 1}", 第二个"{@code 2 }", 第二个"{@code 2 }”, etc. * *

可选标志是一组修改输出*格式的字符。有效标志集取决于转换

可选宽度是一个正小数整数,表示要写入输出的最小字符数。*

可选精度是一个非负十进制整数,通常用来限制字符数。具体行为取决于转换。

所需的转换是一个字符显示参数应当如何被格式化。对于给定参数的无效转换集合
依赖于参数的数据类型

格式化日期

用于表示日期和的类型的格式说明符具有以下语法:

%[argument_index$][flags][width]conversion

所需要的转换是两个字符序列。 第一个字符是{@code ‘t’} or {@code ‘T’}.
第二个字符表示要使用的格式。 这些字符序列是相同的 但不完全相同
完全相同,对于GNU {@code date} 和POSIX {@code strftime(3c)

与参数不一致的格式说明符具有语法:

%[flags][width]conversion

可选标志和宽度定义为上文。

所需的转换是一个字符,指示要插入到输出中的内容。**

Conversions

转换被封为一下几种:

General - may be applied to any argument * type * *
Character - may be applied to basic types which represent * Unicode characters: {@code char}, {@link Character}, {@code byte}, {@link * Byte}, {@code short}, and {@link Short}. This conversion may also be * applied to the types {@code int} and {@link Integer} when {@link * Character#isValidCodePoint} returns {@code true} * *
Numeric * *
* *
Integral - may be applied to Java integral types: {@code byte}, * {@link Byte}, {@code short}, {@link Short}, {@code int} and {@link * Integer}, {@code long}, {@link Long}, and {@link java.math.BigInteger * BigInteger} (but not {@code char} or {@link Character}) * *
Floating Point - may be applied to Java floating-point types: * {@code float}, {@link Float}, {@code double}, {@link Double}, and {@link * java.math.BigDecimal BigDecimal} * *
* *
Date/Time - may be applied to Java types which are capable of * encoding a date or time: {@code long}, {@link Long}, {@link Calendar}, * {@link Date} and {@link TemporalAccessor TemporalAccessor} * *
Percent - produces a literal {@code ‘%’} * (‘\u0025’) * *
Line Separator - produces the platform-specific line separator * *

下面的表总结了支持的转换。转换由一个大写字符标识 (即{@代码‘b’}、{@代码‘h’}、{@代码‘c}、{@代码‘x’}、{@代码‘e’}、{@代码‘g’}、{@代码‘a’}和{@代码‘t’} 与对应的小写转换字符相同 。只是结果被转换成了大写字符 根据流行的规则 {@link java.util.Locale Locale}
结果是和下面的调用等价{@link * String#toUpperCase()} * *

out.toUpperCase()
Conversion *    Argument Category * Description * *
{@code 'b'}, {@code 'B'} *  general *   If the argument arg is {@code null}, then the result is * "{@code false}". If arg is a {@code boolean} or {@link * Boolean}, then the result is the string returned by {@link * String#valueOf(boolean) String.valueOf(arg)}. Otherwise, the result is * "true". * *
{@code 'h'}, {@code 'H'} *  general *   If the argument arg is {@code null}, then the result is * "{@code null}". Otherwise, the result is obtained by invoking * {@code Integer.toHexString(arg.hashCode())}. * *
{@code 's'}, {@code 'S'} *  general *   If the argument arg is {@code null}, then the result is * "{@code null}". If arg implements {@link Formattable}, then * {@link Formattable#formatTo arg.formatTo} is invoked. Otherwise, the * result is obtained by invoking {@code arg.toString()}. * *
{@code 'c'}, {@code 'C'} *  character * The result is a Unicode character * *
{@code 'd'} *   integral *  The result is formatted as a decimal integer * *
{@code 'o'} *   integral *  The result is formatted as an octal integer * *
{@code 'x'}, {@code 'X'} *  integral *  The result is formatted as a hexadecimal integer * *
{@code 'e'}, {@code 'E'} *  floating point *    The result is formatted as a decimal number in computerized * scientific notation * *
{@code 'f'} *   floating point *    The result is formatted as a decimal number * *
{@code 'g'}, {@code 'G'} *  floating point *    The result is formatted using computerized scientific notation or * decimal format, depending on the precision and the value after rounding. * *
{@code 'a'}, {@code 'A'} *  floating point *    The result is formatted as a hexadecimal floating-point number with * a significand and an exponent. This conversion is not supported * for the {@code BigDecimal} type despite the latter's being in the * floating point argument category. * *
{@code 't'}, {@code 'T'} *  date/time * Prefix for date and time conversion characters. See Date/Time Conversions. * *
{@code '%'} *   percent *   The result is a literal {@code '%'} ('\u0025') * *
{@code 'n'} *   line separator *    The result is the platform-specific line separator * *

任何未显式定义为转换的字符都是非法的,并且是为将来扩展保留的。**

Date/Time Conversions

下面的日期和时间转换后缀字符被定义为{@code ‘t’} and {@code ‘T’} 转换。类型与GNU {@code date} and POSIX {@code strftime(3c)}. 所定义的类型相似但不完全相同。提供额外的转换类型以访问Java特定的功能(例如,{@code ‘L’}用于秒内的毫秒。**

下面的conversion 字符集被用作格式化时间:
{@code ‘H’} * Hour of the day for the 24-hour clock, formatted as two digits with * a leading zero as necessary i.e. {@code 00 - 23}. * *
{@code ‘I’} * Hour for the 12-hour clock, formatted as two digits with a leading * zero as necessary, i.e. {@code 01 - 12}. * *
{@code ‘k’} * Hour of the day for the 24-hour clock, i.e. {@code 0 - 23}. * *
{@code ‘l’} * Hour for the 12-hour clock, i.e. {@code 1 - 12}. * *
{@code ‘M’} * Minute within the hour formatted as two digits with a leading zero * as necessary, i.e. {@code 00 - 59}. * *
{@code ‘S’} * Seconds within the minute, formatted as two digits with a leading * zero as necessary, i.e. {@code 00 - 60} (“{@code 60}” is a special * value required to support leap seconds). * *
{@code ‘L’} * Millisecond within the second formatted as three digits with * leading zeros as necessary, i.e. {@code 000 - 999}. * *
{@code ‘N’} * Nanosecond within the second, formatted as nine digits with leading * zeros as necessary, i.e. {@code 000000000 - 999999999}. * *
{@code ‘p’} * Locale-specific {@linkplain * java.text.DateFormatSymbols#getAmPmStrings morning or afternoon} marker * in lower case, e.g.”{@code am}” or “{@code pm}”. Use of the conversion * prefix {@code ‘T’} forces this output to upper case. * *
{@code ‘z’} * RFC 822 * style numeric time zone offset from GMT, e.g. {@code -0800}. This * value will be adjusted as necessary for Daylight Saving Time. For * {@code long}, {@link Long}, and {@link Date} the time zone used is * the {@linkplain TimeZone#getDefault() default time zone} for this * instance of the Java virtual machine. * *
{@code ‘Z’} * A string representing the abbreviation for the time zone. This * value will be adjusted as necessary for Daylight Saving Time. For * {@code long}, {@link Long}, and {@link Date} the time zone used is * the {@linkplain TimeZone#getDefault() default time zone} for this * instance of the Java virtual machine. The Formatter’s locale will * supersede the locale of the argument (if any). * *
{@code ‘s’} * Seconds since the beginning of the epoch starting at 1 January 1970 * {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE/1000} to * {@code Long.MAX_VALUE/1000}. * *
{@code ‘Q’} * Milliseconds since the beginning of the epoch starting at 1 January * 1970 {@code 00:00:00} UTC, i.e. {@code Long.MIN_VALUE} to * {@code Long.MAX_VALUE}. * *

下面的conversion字符集被用作格式化日期

{@code ‘B’} * Locale-specific {@linkplain java.text.DateFormatSymbols#getMonths * full month name}, e.g. {@code “January”}, {@code “February”}. * *
{@code ‘b’} * Locale-specific {@linkplain * java.text.DateFormatSymbols#getShortMonths abbreviated month name}, * e.g. {@code “Jan”}, {@code “Feb”}. * *
{@code ‘h’} * Same as {@code ‘b’}. * *
{@code ‘A’} * Locale-specific full name of the {@linkplain * java.text.DateFormatSymbols#getWeekdays day of the week}, * e.g. {@code “Sunday”}, {@code “Monday”} * *
{@code ‘a’} * Locale-specific short name of the {@linkplain * java.text.DateFormatSymbols#getShortWeekdays day of the week}, * e.g. {@code “Sun”}, {@code “Mon”} * *
{@code ‘C’} * Four-digit year divided by {@code 100}, formatted as two digits * with leading zero as necessary, i.e. {@code 00 - 99} * *
{@code ‘Y’} * Year, formatted as at least four digits with leading zeros as * necessary, e.g. {@code 0092} equals {@code 92} CE for the Gregorian * calendar. * *
{@code ‘y’} * Last two digits of the year, formatted with leading zeros as * necessary, i.e. {@code 00 - 99}. * *
{@code ‘j’} * Day of year, formatted as three digits with leading zeros as * necessary, e.g. {@code 001 - 366} for the Gregorian calendar. * *
{@code ‘m’} * Month, formatted as two digits with leading zeros as necessary, * i.e. {@code 01 - 13}. * *
{@code ‘d’} * Day of month, formatted as two digits with leading zeros as * necessary, i.e. {@code 01 - 31} * *
{@code ‘e’} * Day of month, formatted as two digits, i.e. {@code 1 - 31}. * *
* *

The following conversion characters are used for formatting common * date/time compositions. * * * *
{@code ‘R’} * Time formatted for the 24-hour clock as {@code “%tH:%tM”} * *
{@code ‘T’} * Time formatted for the 24-hour clock as {@code “%tH:%tM:%tS”}. * *
{@code ‘r’} * Time formatted for the 12-hour clock as {@code “%tI:%tM:%tS %Tp”}. * The location of the morning or afternoon marker ({@code ‘%Tp’}) may be * locale-dependent. * *
{@code ‘D’} * Date formatted as {@code “%tm/%td/%ty”}. * *
{@code ‘F’} * ISO 8601 * complete date formatted as {@code “%tY-%tm-%td”}. * *
{@code ‘c’} * Date and time formatted as {@code “%ta %tb %td %tT %tZ %tY”}, * e.g. {@code “Sun Jul 20 16:17:00 EDT 1969”}. * *

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

Flags

下表总结了所支持的标志。Y意味着*标志对于所指示的参数类型是支持的。

java代码模拟form data请求 formatter java_Java

Width
宽度是要写入到输出的最小字符数。对于行分隔符转换,宽度不适用;如果提供了,将抛出异常。*

Precision
对于一般参数类型,精度是要写入输出的最大字符数。

对于浮点转换{@code ‘a’}, {@code ‘A’}, {@code ‘e’}, * {@code ‘E’}, and {@code ‘f’}
精度是小数点的位数。

如果转换是{@code ‘g’} or {@code ‘G’},
precision 是四舍五入后得到的大小的总数

对于 character, integral, and date/time 参数类型 和he percent * and line separator 等conversions,精度不应用 如果一个精度被提供 则抛出异常

Argument Index(参数索引)
参数索引是一个十进制整数。指示参数列表中参数的位置。第一个参数由{@code 1}"引用,第二个由{@code 2 }"引用,第二个由{@code 2 }引用等等

另一种引用位置的方法是使用{@code ‘<’} (‘\u003c’) 标记,
这标志着前面的格式说明符被重用

例如,下面的两个语句将产生相同的字符串

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);

更多细节请参考jdk api