Unravel โบ Java concepts โบ Strings and text
Formatting text and numbers
String.format("%s has %d items (%.2f%%)", name, n, pct) builds text from a template with placeholders.
Learn these first
At a glance
A mail-merge letter: the template has gaps ("Dear %s"), and the program fills each gap with a value and the right formatting.
- 1Placeholders: %s text, %d whole number, %f decimal, %.2f two decimals, %n newline, %x hex, %,d with thousand separators, %5d padded to width 5, %-10s left aligned, %% a literal percent sign
- 2printf is System.out.print(String.format(...)); "...".formatted(args) (Java 15) is the same on a string
- 3Format uses the default locale: in Germany %.2f prints 3,14Pass a Locale (String.format(Locale.US, ...)) when the output is for a file, JSON or another machine.
- 4NumberFormat.getCurrencyInstance(Locale.US).format(12.5) gives $12.50; DecimalFormat("#,##0.00") gives control of the pattern
- A wrong placeholder type is a run-time error (IllegalFormatConversionException, e.g
- Never format money with double; use BigDecimal and format at the edge
- String.format parses the template with a regular expression every call, which makes it slow in hot loops
import java.util.Locale;public class Receipt { static String line(String item, int qty, double price) { return String.format(Locale.US, "%-12s x%2d %8.2f", item, qty, price * qty); } static void print(String name, int count) { System.out.printf("%s has %,d items%n", name, count); }}- line 4 uses format, the core of Formatting text and numbers
- line 7 uses printf, the core of Formatting text and numbers
Read the full explanation (about 1 min)
String.format("%s has %d items (%.2f%%)", name, n, pct) builds text from a template with placeholders. DecimalFormat and NumberFormat format numbers and currency for a locale.
A mental model
A mail-merge letter: the template has gaps ("Dear %s"), and the program fills each gap with a value and the right formatting.
How it works
Placeholders: %s text, %d whole number, %f decimal, %.2f two decimals, %n newline, %x hex, %,d with thousand separators, %5d padded to width 5, %-10s left aligned, %% a literal percent sign.
printf is System.out.print(String.format(...)); "...".formatted(args) (Java 15) is the same on a string.
Format uses the default locale: in Germany %.2f prints 3,14. Pass a Locale (String.format(Locale.US, ...)) when the output is for a file, JSON or another machine.
NumberFormat.getCurrencyInstance(Locale.US).format(12.5) gives $12.50; DecimalFormat("#,##0.00") gives control of the pattern.
Going deeper
A wrong placeholder type is a run-time error (IllegalFormatConversionException, e.g. %d with a double) and too few arguments gives MissingFormatArgumentException. The compiler does not check.
Never format money with double; use BigDecimal and format at the edge. NumberFormat and DecimalFormat are not thread safe: do not share one instance in a static field.
In logging, use the {} placeholders of SLF4J instead of String.format; they skip the work if the level is off.
Under the hood
String.format parses the template with a regular expression every call, which makes it slow in hot loops. A Formatter object writes into an Appendable and can be reused for many lines.
Common mistakes
%dwith adouble, or%sexpected and a missing argument.- Depending on the default locale for machine-readable output.
- Sharing a
DecimalFormatbetween threads.
How Unravel recognises it
When you paste code, Unravel looks for these signs of formatting text and numbers. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
DecimalFormatNumberFormatMessageFormatFormatter - Method calls:
String.format()formatted()printf()NumberFormat.getCurrencyInstance()NumberFormat.getInstance() - Created with new:
DecimalFormat
Part of a learning path
- Text, numbers and arrays ยท previous: Strings: immutability, equality, common methods ยท next: Characters, Unicode and encodings
Related concepts
Frequently asked questions
What is Formatting text and numbers?
String.format("%s has %d items (%.2f%%)", name, n, pct) builds text from a template with placeholders. DecimalFormat and NumberFormat format numbers and currency for a locale.
What are the most common mistakes with Formatting text and numbers?
%d with a double, or %s expected and a missing argument. Depending on the default locale for machine-readable output. Sharing a DecimalFormat between threads.
How can I see Formatting text and numbers in real code?
Paste your own Java into Unravel and it will point out where formatting text and numbers appears, explain how it works at the detail level you choose, and draw the flow of the code around it.