本教程是针对JDK 8编写的。本页中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
有关Java SE 9及其后续版本中更新的语言特性的概述,请参阅Java语言更改。
有关所有JDK版本的新功能、增强功能以及已删除或不建议使用的选项的信息,请参阅JDK发布说明。
实现格式化的流对象是PrintWriter和PrintStream的实例,它们分别是字符流类和字节流类。
System.out和System.err这两个PrintStream对象。(有关这些对象的更多信息,请参阅从命令行进行I/O操作。)当你需要创建一个格式化的输出流时,请实例化PrintWriter而不是PrintStream。
和所有的字节流和字符流对象一样,PrintStream和PrintWriter的实例都实现了一组用于简单字节和字符输出的write方法。此外,PrintStream和PrintWriter还实现了相同的一组方法,用于将内部数据转换为格式化的输出。提供了两个级别的格式化:
print和println以标准方式格式化单个值。format根据格式字符串格式化几乎任意数量的值,具有许多精确格式化的选项。print和println方法调用print或println在转换值使用适当的toString方法后输出一个单个值。我们可以在Root示例中看到这一点:
public class Root {
public static void main(String[] args) {
int i = 2;
double r = Math.sqrt(i);
System.out.print("The square root of ");
System.out.print(i);
System.out.print(" is ");
System.out.print(r);
System.out.println(".");
i = 5;
r = Math.sqrt(i);
System.out.println("The square root of " + i + " is " + r + ".");
}
}
下面是Root的输出结果:
The square root of 2 is 1.4142135623730951. The square root of 5 is 2.23606797749979.
i和r变量被格式化了两次:第一次使用print的重载中的代码,第二次由Java编译器自动生成的转换代码,它也使用了toString。你可以以这种方式格式化任何值,但对结果的控制力有限。
format方法根据一个格式字符串格式化多个参数。格式字符串由静态文本和格式说明符组成;除了格式说明符,格式字符串的输出保持不变。
格式字符串支持很多特性。在本教程中,我们只涵盖一些基础知识。完整的描述请参见API规范中的格式字符串语法。
Root2示例使用单个format调用来格式化两个值:
public class Root2 {
public static void main(String[] args) {
int i = 2;
double r = Math.sqrt(i);
System.out.format("平方根:%d 是 %f。%n", i, r);
}
}
这是输出结果:
平方根:2 是 1.414214。
像本示例中使用的三个格式说明符一样,所有的格式说明符以%开头,并以一个或两个字符的转换结尾,用于指定正在生成的格式化输出的类型。这里使用的三个转换是:
d将整数值格式化为十进制值。f将浮点值格式化为十进制值。n输出特定于平台的换行符。这里还有一些其他的转换:
x将整数格式化为十六进制值。s将任意值格式化为字符串。tB将整数格式化为与区域设置相关的月份名称。还有很多其他的转换。
除了%%和%n之外,所有的格式说明符都必须与参数匹配。如果不匹配,将抛出异常。
在Java编程语言中,\n转义序列总是生成换行符(\u000A)。除非你明确想要换行符,否则不要使用\n。要获取本地平台的正确行分隔符,请使用%n。
除了转换,格式说明符还可以包含多个额外的元素,进一步自定义格式化输出。这是一个使用了所有可能元素的示例,Format。
public class Format {
public static void main(String[] args) {
System.out.format("%f, %1$+020.10f %n", Math.PI);
}
}
这是输出结果:
3.141593, +00000003.1415926536
其他元素都是可选的。下图显示了较长的格式化指示符是如何分解成元素的。
格式化指示符的元素。
这些元素必须按照所示的顺序出现。从右到左,可选的元素有:
s和其他一般转换来说,这是格式化值的最大宽度;如果需要,值将被右截断。Format示例中,+标志指定数字应始终带有符号,0标志指定0是填充字符。其他标志包括-(右侧填充)和,(使用特定于区域设置的千位分隔符格式化数字)。请注意,某些标志不能与某些其他标志或某些转换一起使用。<来匹配与前一个指示符相同的参数。因此,示例可以这样写:System.out.format("%f, %<+020.10f %n", Math.PI);