Reconsidering System.out.format().

exercise No. 124

Q:

This exercise aims at a better understanding of System.out.format() already being used in Tidy up the mess! and other exercises. Consider the following snippet:

int value = 33;
double secondValue = 114.317;

System.out.format("Just a single integer %3d\n", value);

System.out.format("An integer %3d and a double value %6.2f\n",
                              value,                 secondValue);

Something seems to be odd here: The format() method is being called with a different number of arguments. Actually we may call it with an arbitrary number of one or more arguments. Answer the following two questions:

  1. How does this work (syntactically) ?

  2. What is the role of the %... format strings?

A:

  1. At first sight these method calls appear as if the format() method had been multiply overloaded. This observation is misleading despite the fact that a related overloaded method providing an additional locale argument does indeed exist.

    According to System.out.format(...) the first argument must be of type String. Additional arguments of arbitrary type may be added in accordance with the %... format strings inside the first argument. It uses the varargs mechanism being described in the Java classes section of chapter 4 of [Kurniawan].

  2. There is a one to one correspondence between each %... format string and its corresponding argument: If n further arguments exist the format string must contain n % format specifiers.

Consider the following snippet:

final int v = 33;
final double d = 114.317;
final short color = 255;

System.out.format("v=%d, d=%5.2f, color=%2x\n", v, d, color);

This generates the following output:

v=33, d=114.32, color=ff

We may prettify our code to better reflect the one to one correspondence between format strings and variables:

System.out.format("v=%d, d=%5.2f, color=%2x\n",
                      v,    d,           color);

Caution

A failure in providing appropriate numbers of arguments having appropriate types likely results in a runtime exception:

System.out.format("v=%d, d=%d, color=%2x\n", // Error: Using %s
                                             // rather than %f.
                           v,    d,           color);
v=33, d=Exception in thread "main"
java.util.IllegalFormatConversionException: d != java.lang.Double
	at java.util.Formatter$FormatSpecifier.failConversion(...