🔤 Strings & Text · Beginner

Formatting text in Java

String.format, formatted(), printf format specifiers %d %s %.2f %n.

🧩 The mysteryYour shop prints 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"
🔮 Predict it

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"));
  1. 2.71 [ 7] [ab ]
  2. 2.72 [ 7] [ab ]
  3. 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.

🔮 Predict it

A risky placeholder

The compiler doesn't check format strings. What happens here?

String s = String.format("%d", 3.5);
System.out.println(s);
  1. 3
  2. 4
  3. 3.5
  4. Throws 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.

⚠️ The trap

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 the real world

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

  1. %d integers, %s anything, %f decimals, %n newline
  2. %.2f rounds to 2 decimal places
  3. %5d right-aligns in 5 columns, %-5s left-aligns
  4. A wrong type for a specifier throws at runtime
🤯 Did you know?

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);
  1. Ada is 36
  2. %s is %d
  3. Ada is 36%n
  4. 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"));
  1. 3.14 42| ab |
  2. 3.14159 42 | ab|
  3. 3.15 42| ab |
  4. 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.

Next: pasting a block of JSON into Java without drowning in \" and \n — text blocks.