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 Unlock

  • String.format() returns a formatted String.
  • 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(), and String.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.5

The 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.50

The 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

APITypical formResult
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 %n for a platform-appropriate line separator.
  • formatted() is convenient when the template itself is a string literal or variable. It uses the default formatting locale; use String.format(Locale, ...) or printf(Locale, ...) when an explicit locale is required.
  • String.format() and formatted() return String results. For very large repeated construction workloads, consider whether a formatter is appropriate or whether a StringBuilder is a better fit.

Choosing a formatting API

Whiteboard
Loading diagram...

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:

  1. % starts the specifier.
  2. argument_index$ is optional and selects a one-based argument position.
  3. flags optionally control alignment, padding, signs, or grouping.
  4. width optionally specifies the minimum output width.
  5. .precision optionally controls precision for supported conversions.
  6. conversion is required and determines how the value is rendered.

Examples:

SpecifierMeaning
%sString representation without minimum padding.
%10sString in a minimum width of ten, right-aligned by default.
%-10sString in a minimum width of ten, left-aligned.
%05dInteger in a minimum width of five, zero-padded.
%,.2fFloating-point value with grouping and two fractional digits.
%1$sUse the first argument as a string.
%2$dUse the second argument as an integer.
%-12.3fLeft-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

Whiteboard
Loading diagram...

6. Common Conversion Specifiers

The conversion letter is the final part of a format specifier.

ConversionTypical accepted valueExampleMeaning
%sAny value"Mouse" → MouseString representation; generally calls toString() for non-null objects.
%dIntegral types and BigInteger42 → 42Decimal integer.
%fFloating-point types and BigDecimal19.5 → 19.500000Decimal floating-point form; default precision is six fractional digits.
%eFloating-point values19500.0 → 1.950000e+04Scientific notation.
%x / %XIntegral values255 → ff / FFLowercase / uppercase hexadecimal.
%oIntegral values8 → 10Octal representation.
%bAny valuetrue → trueBoolean representation; null prints false.
%cchar or a valid integer code point'A' → ACharacter.
%nNo 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

  • %s is flexible and prints null as the text null. It should not be used indiscriminately when a numeric conversion would better expose type mistakes.
  • %f defaults to six fractional digits, so %.2f is common for two-decimal display.
  • %n is a formatting directive, not the literal characters \ and n. It requests the platform line separator.
  • %% prints one literal %. To display 15% off followed by a line break, write 15%% off%n.
  • %b is not a general-purpose conversion to the text "true" for every non-null object. For formatting, null produces false; a non-null value generally produces true unless it is a Boolean with value false.

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|

  • %10s uses a minimum width of ten and right-aligns the string by default.
  • %-10s uses a minimum width of ten and left-aligns the string.
  • %4s does 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 %f and %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 throw IllegalFormatPrecisionException.

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.

FlagMeaningExample
-Left-align within the specified width%-10s
0Pad 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
spaceInclude 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.US when 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

ExceptionCommon causeHow to prevent it
IllegalFormatConversionExceptionConversion letter does not match the argument typeMatch conversions to values, such as %d for integral values and %f for floating-point values.
MissingFormatArgumentExceptionA format specifier has no corresponding argumentCount placeholders and supplied values.
IllegalFormatPrecisionExceptionPrecision is invalid for the selected conversionUse precision only where supported; use width for integer padding.
UnknownFormatConversionExceptionUnknown conversion characterCheck the conversion letter and the full specifier.
FormatFlagsConversionMismatchExceptionA flag is incompatible with the conversionUse flags supported by that conversion.
IllegalFormatFlagsExceptionConflicting or invalid flag combinationRemove conflicting flags and verify the format syntax.
MissingFormatWidthExceptionA flag that requires width is used without a widthSupply the required width, such as %-10s.

15. Formatting Recipes

Currency-like display

Output

 $12,345.60

This 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-000073

Zero-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, StringBuilder may be a better fit than repeatedly calling String.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 %.2f when two fractional digits are required for display.
  • Use %n for 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 %s precision 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 %s as a universal substitute for a meaningful conversion such as %d or %.2f.
  • Do not use display formatting as a replacement for correct numeric or financial calculations.

18. Quick Revision Notes

  • String.format() returns a formatted String.
  • System.out.printf() writes formatted output and does not add a newline unless %n is included.
  • String.formatted() is available from Java 15.
  • The general syntax is %[argument_index$][flags][width][.precision]conversion.
  • %s renders a string representation; %d formats integral values; %f formats decimal floating-point values.
  • %n adds a platform line separator; %% prints a literal percent sign.
  • Width is a minimum; precision depends on the conversion.
  • - left-aligns; 0 zero-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 StringBuilder for 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.