Formatting text in Java
String.format, formatted(), printf format specifiers %d %s %.2f %n.
Total: 0.30000000000000004. Customers panic. Five characters fix it: %.2f. Welcome to format specifiers.Fill in the blanks
A format string is a sentence with placeholders. %s takes any value as text, %d an integer, %f a decimal, and %n adds a line break. The arguments fill the placeholders in order.
String s = String.format(
"%s is %d", "Ada", 36);
// "Ada is 36"Three ways to format
String.format(fmt, args) is static and returns a String. fmt.formatted(args) (Java 15) is an instance method — the String itself is the format. System.out.printf(fmt, args) prints directly.
String.format("%d items", 5);
"%d items".formatted(5);
System.out.printf("%d items%n", 5);Precision and width
%.2f rounds to 2 decimals. A width like %5d pads with spaces on the left (right-aligns) to 5 columns; %-5s pads on the right (left-aligns). %03d pads with zeros: 7 becomes 007.
String.format("%.1f", 3.14159); // "3.1"
String.format("%03d", 7); // "007"Line it up
What does this print?
String a = String.format("%.2f", 2.71828);
System.out.println(a);
System.out.println("[%4d]".formatted(7));
System.out.println("[%-4s]".formatted("ab"));2.71 [ 7] [ab ]2.72 [ 7] [ab ]2.72 [7 ] [ ab]
Show the answer
2.72 (rounded, not cut off), then 7 pushed right inside 4 columns, then ab pushed left because of the - flag.
A risky placeholder
The compiler doesn't check format strings. What happens here?
String s = String.format("%d", 3.5);
System.out.println(s);343.5Throws IllegalFormatConversionException
Show the answer
It throws IllegalFormatConversionException. %d only accepts integer types, and a double is discovered at runtime. Use %f (or %.1f) for decimals.
format vs formatted
"Total: %d".format(5) looks right but doesn't compile: format is static and expects the format String as its first argument. Use "Total: %d".formatted(5) or String.format("Total: %d", 5). And printf belongs to System.out, not to String.
"Total: %d".format(5); // compile error
"Total: %d".formatted(5); // "Total: 5"%n vs \n
%n produces the platform's line separator (System.lineSeparator(): \r\n on Windows, \n elsewhere). A literal \n is always just a line feed. In format strings, %n is the portable choice.
In real projects
Invoices, reports and log lines all rely on formatting. Two production gotchas: format money for display only (calculate with BigDecimal), and remember String.format uses the default locale — on a German server %.2f prints 3,14, which can break a CSV file.
Key takeaways
- %d integers, %s anything, %f decimals, %n newline
- %.2f rounds to 2 decimal places
- %5d right-aligns in 5 columns, %-5s left-aligns
- A wrong type for a specifier throws at runtime
Add a comma flag for thousands: String.format("%,d", 1234567) gives 1,234,567 in an English locale.
Practice questions
What does this print?
System.out.printf("%s is %d%n", "Ada", 36);- Ada is 36
- %s is %d
- Ada is 36%n
- Ada is %d
Check your answer
Ada is 36. printf replaces %s with "Ada", %d with 36, and %n with a newline.
What does this print?
System.out.println(String.format("%.2f", 3.14159));
System.out.println("%5d|".formatted(42));
System.out.println("%-5s|".formatted("ab"));- 3.14 42| ab |
- 3.14159 42 | ab|
- 3.15 42| ab |
- 3.14 42 | ab|
Check your answer
3.14 42| ab |. %.2f rounds to two decimals. A width pads with spaces on the left; the - flag pads on the right instead.