1. Introduction
Building clean output with ordinary string concatenation becomes difficult when values need specific decimal places, aligned columns, zero-padding, thousands separators, or consistent spacing. Java provides formatting tools that separate the template from the values:
Premium Video
This video is available to Premium members or users who have purchased the course.
Sign in to UnlockString.format()returns a formattedString.System.out.printf()writes formatted text directly to standard output.String.formatted()formats the string on which the method is called. It was added in Java 15.
These APIs use the same general format-specifier syntax. The main difference is where the formatted text goes.
This guide explains the syntax, common conversion letters, width, precision, flags, argument indexes, locale, text blocks, common runtime exceptions, and practical formatting patterns. It uses runnable examples with public class Main, as required by the ExamAdda Java runner.
2. Learning Objectives
By the end of this guide, you should be able to:
- Explain why formatting is useful compared with repeated concatenation.
- Choose between
String.format(),printf(), andString.formatted(). - Read and construct format specifiers.
- Use common conversions such as
%s,%d,%f,%e,%x,%b,%c,%n, and%%. - Control minimum width, precision, alignment, padding, signs, and digit grouping.
- Reuse and reorder arguments with argument indexes.
- Choose a locale when output must be predictable.
- Use a text block as a multi-line format template.
- Recognize common formatting exceptions and avoid mismatched specifiers.
3. Why String Formatting Exists
Imagine printing a receipt with an order ID padded to five digits, a customer name aligned in a fixed-width column, and a price with exactly two decimal places. With concatenation, each formatting requirement needs extra logic.
Output
Order: 73 | Customer: Asha | Total: $2499.5The result is valid, but the ID has no leading zeros and the price has no fixed two-decimal representation. A format string describes these requirements in one template.
Output (with a US-style locale)
Order: 00073 | Customer: Asha | Total: $2,499.50The template describes the output:
%05d— render the integer in a minimum width of five, padding with zeros.%-10s— render the string left-aligned in a minimum width of ten.%,.2f— render a floating-point value with grouping separators and two digits after the decimal point.
4. The Three Main Formatting APIs
| API | Typical form | Result |
|---|---|---|
String.format() | String.format("%s: %.2f", name, price) | Returns a formatted String. |
System.out.printf() | System.out.printf("%s: %.2f%n", name, price) | Writes formatted text to standard output. |
String.formatted() | "%s: %.2f".formatted(name, price) | Returns a formatted String; available since Java 15. |
Complete example
Output
Wireless Mouse: $24.50
Wireless Mouse: $24.50
Wireless Mouse costs $24.50
Important differences
String.format()returns text; it does not print by itself.printf()writes text directly and does not append a newline automatically. Use%nfor a platform-appropriate line separator.formatted()is convenient when the template itself is a string literal or variable. It uses the default formatting locale; useString.format(Locale, ...)orprintf(Locale, ...)when an explicit locale is required.String.format()andformatted()returnStringresults. For very large repeated construction workloads, consider whether a formatter is appropriate or whether aStringBuilderis a better fit.
Choosing a formatting API
println() versus printf()
println(value) prints the value and adds a line separator. printf(format, args...) interprets the first argument as a format string and does not add a line separator unless the format contains %n.
5. Anatomy of a Format Specifier
A common format specifier has this general structure:
The order matters:
%starts the specifier.argument_index$is optional and selects a one-based argument position.flagsoptionally control alignment, padding, signs, or grouping.widthoptionally specifies the minimum output width..precisionoptionally controls precision for supported conversions.conversionis required and determines how the value is rendered.
Examples:
| Specifier | Meaning |
|---|---|
%s | String representation without minimum padding. |
%10s | String in a minimum width of ten, right-aligned by default. |
%-10s | String in a minimum width of ten, left-aligned. |
%05d | Integer in a minimum width of five, zero-padded. |
%,.2f | Floating-point value with grouping and two fractional digits. |
%1$s | Use the first argument as a string. |
%2$d | Use the second argument as an integer. |
%-12.3f | Left-aligned floating-point output, minimum width 12, precision 3. |
A malformed specifier or a mismatch between the specifier and its argument can throw a runtime formatting exception.
Format-specifier reading flowchart
6. Common Conversion Specifiers
The conversion letter is the final part of a format specifier.
| Conversion | Typical accepted value | Example | Meaning |
|---|---|---|---|
%s | Any value | "Mouse" → Mouse | String representation; generally calls toString() for non-null objects. |
%d | Integral types and BigInteger | 42 → 42 | Decimal integer. |
%f | Floating-point types and BigDecimal | 19.5 → 19.500000 | Decimal floating-point form; default precision is six fractional digits. |
%e | Floating-point values | 19500.0 → 1.950000e+04 | Scientific notation. |
%x / %X | Integral values | 255 → ff / FF | Lowercase / uppercase hexadecimal. |
%o | Integral values | 8 → 10 | Octal representation. |
%b | Any value | true → true | Boolean representation; null prints false. |
%c | char or a valid integer code point | 'A' → A | Character. |
%n | No argument | — | Platform-specific line separator. |
%% | No argument | — | Literal percent sign. |
Example covering common conversions
Output
Product: Wireless Mouse
Count: 42
Price: 19.50
Scientific: 1.950000e+01
Hex: ff
Hex uppercase: FF
Octal: 10
Boolean: true
Grade: A
Discount: 15% off
Notes about special conversions
%sis flexible and printsnullas the textnull. It should not be used indiscriminately when a numeric conversion would better expose type mistakes.%fdefaults to six fractional digits, so%.2fis common for two-decimal display.%nis a formatting directive, not the literal characters\andn. It requests the platform line separator.%%prints one literal%. To display15% offfollowed by a line break, write15%% off%n.%bis not a general-purpose conversion to the text"true"for every non-null object. For formatting, null producesfalse; a non-null value generally producestrueunless it is aBooleanwith valuefalse.
7. Width and Alignment
Width sets the minimum number of characters used for the formatted value. If the result is shorter, Java pads it. If the value is longer, Java prints the full value; width does not truncate it.
Output
| Mouse|
|Mouse |
|Wireless Mouse|
%10suses a minimum width of ten and right-aligns the string by default.%-10suses a minimum width of ten and left-aligns the string.%4sdoes not cut"Wireless Mouse"down to four characters.
Width is useful for console tables, reports, and receipt columns. For complex tabular output, remember that character width is not necessarily the same as visual display width for every Unicode character or terminal font.
8. Precision
Precision is written with a dot followed by a number, such as .2.
Its meaning depends on the conversion:
- For
%fand%e, precision controls the number of digits after the decimal point. - For
%s, precision limits the number of characters included in the output. - Precision is not supported for
%d; using it can throwIllegalFormatPrecisionException.
Output
Default: 24.567000
Two decimals: 24.57
No decimals: 25
First five chars: Wirel
Formatting a floating-point value to a given precision rounds the displayed representation; it does not mutate the original numeric value. For currency calculations, use an appropriate numeric type and rounding policy rather than treating display formatting as a substitute for financial arithmetic.
9. Useful Flags
Flags appear between the optional argument index and width.
| Flag | Meaning | Example |
|---|---|---|
- | Left-align within the specified width | %-10s |
0 | Pad a numeric value with zeros | %05d |
, | Use locale-sensitive grouping separators | %,d |
+ | Always include a sign for numeric values | %+d |
( | Put negative numeric values in parentheses | %(d |
| space | Include a leading space for positive numeric values in supported conversions | % d |
Combined flags
Output
ID: 00042
Revenue: +1,234,567
Loss: (1,234.50)
Price: 24.50 |
Signed: +5
Not every flag is valid with every conversion. For example, zero-padding is intended for numeric output, and incompatible flag combinations can produce FormatFlagsConversionMismatchException or another IllegalFormatException subtype.
10. Argument Indexes and Reusing Values
Arguments are consumed from left to right by default. The syntax n$ selects a particular argument using a one-based index: %1$s refers to the first argument, %2$s to the second, and so on.
Output
Asha purchased an item. Thank you, Asha!
Quantity: 3 | Product: Wireless Mouse
Argument indexes are especially useful when a value appears several times or when translated templates need to rearrange the order of values without changing the argument list.
11. Locale-Sensitive Formatting
A locale can affect decimal separators, grouping separators, and other conventions. For example, the same number may appear as 1,234.56 in a US-style format and 1.234,56 in a German-style format.
The default String.format() and printf() methods use the JVM's default formatting locale. That can make output vary across machines and test environments.
Typical output
1,234.56
1.234,56
1 234,56
The French grouping separator may be a non-breaking or narrow non-breaking space depending on the JDK and locale data. Therefore, visually similar output may not always contain an ordinary ASCII space.
Choosing a locale
- Use
Locale.USwhen you explicitly want US-style decimal and grouping conventions. - Use a locale appropriate for the user when presenting localized numbers.
- Use an explicit locale for output that is compared in tests or consumed by another program.
- For machine-readable data, consider using a locale-independent format or a serialization format designed for that purpose rather than relying on human-oriented formatting.
String.formatted() does not accept a locale argument and uses the default formatting locale. When locale control matters, prefer String.format(Locale, ...) or printf(Locale, ...).
12. Text Blocks as Multi-Line Format Templates
Java 15 introduced text blocks, which use triple quotes (""") to express multi-line string literals. A text block can be formatted with .formatted(...), String.format(...), or printf(...).
Output
ORDER RECEIPT
-------------
Order ID : 00073
Customer : Asha
Total : $2,499.50
Status : PAID
Text blocks make longer templates easier to read because the source resembles the intended output. They do not introduce a separate formatting syntax: the same specifiers and rules still apply. Text blocks and String.formatted() both require Java 15 or later.
13. Common Formatting Exceptions
Format strings are checked primarily at runtime. The compiler usually cannot prove that each conversion matches the corresponding argument.
13.1 Wrong conversion for the value
This throws IllegalFormatConversionException because %d expects an integral value, not a double.
Correction
13.2 Too few arguments
The format requires two values but receives only one, so Java throws MissingFormatArgumentException.
Correction
13.3 Invalid precision for an integer
Precision is not supported for %d, so this throws IllegalFormatPrecisionException.
Correction
This uses width and zero-padding instead of precision.
13.4 Forgetting to escape a percent sign
Incorrect:
A percent sign starts a format specifier, so the lone % can cause an invalid-format exception.
Correct:
13.5 Argument order mismatch
If the template starts with %d but the first argument is a double, Java throws a conversion exception. Either pass arguments in the expected order or use argument indexes such as %2$d items at $%1$.2f each.
14. Exception Reference Table
| Exception | Common cause | How to prevent it |
|---|---|---|
IllegalFormatConversionException | Conversion letter does not match the argument type | Match conversions to values, such as %d for integral values and %f for floating-point values. |
MissingFormatArgumentException | A format specifier has no corresponding argument | Count placeholders and supplied values. |
IllegalFormatPrecisionException | Precision is invalid for the selected conversion | Use precision only where supported; use width for integer padding. |
UnknownFormatConversionException | Unknown conversion character | Check the conversion letter and the full specifier. |
FormatFlagsConversionMismatchException | A flag is incompatible with the conversion | Use flags supported by that conversion. |
IllegalFormatFlagsException | Conflicting or invalid flag combination | Remove conflicting flags and verify the format syntax. |
MissingFormatWidthException | A flag that requires width is used without a width | Supply the required width, such as %-10s. |
15. Formatting Recipes
Currency-like display
Output
$12,345.60This is a display example, not a recommendation to use double for financial arithmetic.
Fixed-width console columns
Output
PRODUCT PRICE
Mouse 24.50
Keyboard 59.99
Zero-padded identifiers
Output
ORD-000073Zero-padding is a presentation choice. It does not change the underlying integer value.
16. Performance and Practical Guidance
Formatting is convenient, but it has work to do: parse the format string, check the arguments, convert values, apply padding, and construct output.
- For occasional human-readable output, formatting is usually worth the clarity.
- For direct console output,
printf()avoids the need to store a separate formatted string first. - For repeated string assembly in a performance-sensitive loop,
StringBuildermay be a better fit than repeatedly callingString.format(). - Avoid assuming that formatting is free, but do not optimize ordinary code without evidence.
- If performance matters, benchmark representative workloads with a proper benchmark harness such as JMH.
Use formatting when the template's structure and output requirements benefit from being explicit.
17. Best Practices
- Match each conversion to the intended value type.
- Use
%.2fwhen two fractional digits are required for display. - Use
%nfor a platform-appropriate newline inside format strings. - Use
%%to render a literal percent sign. - Remember that width is a minimum and does not truncate long values.
- Remember that
%sprecision truncates the displayed string. - Use argument indexes when values must be reused or reordered.
- Pass an explicit locale when output must be stable across machines.
- Prefer
String.format(Locale, ...)when locale control is important. - Use text blocks for readable multi-line templates on Java 15+.
- Keep format strings and their arguments close together to make mismatches easier to review.
- Avoid using
%sas a universal substitute for a meaningful conversion such as%dor%.2f. - Do not use display formatting as a replacement for correct numeric or financial calculations.
18. Quick Revision Notes
String.format()returns a formattedString.System.out.printf()writes formatted output and does not add a newline unless%nis included.String.formatted()is available from Java 15.- The general syntax is
%[argument_index$][flags][width][.precision]conversion. %srenders a string representation;%dformats integral values;%fformats decimal floating-point values.%nadds a platform line separator;%%prints a literal percent sign.- Width is a minimum; precision depends on the conversion.
-left-aligns;0zero-pads supported numeric conversions;,groups digits;+forces a sign;(can parenthesize negative values.- Argument indexes start at 1, not 0.
- Locale can change decimal and grouping separators.
- Format mismatches can throw runtime exceptions.
- Use
StringBuilderfor repeated dynamic assembly when formatting overhead is unnecessary.
19. Conclusion
Java's formatting APIs make output easier to read and maintain by separating the layout template from the values. String.format() is useful when the formatted text must be stored, printf() is convenient for direct output, and String.formatted() provides a compact instance-style option on Java 15 and later.
Understanding conversion letters, width, precision, flags, argument indexes, and locale helps prevent subtle bugs and produces predictable output. For human-facing output, formatting can make receipts, reports, and console tables much clearer. For machine-readable output, use explicit locale and an appropriate data format. As with any API, choose formatting for clarity and use profiling to guide performance decisions.