Java printf: Format Specifiers, Width, Precision and Flags
How System.out.printf and String.format work in Java: %d, %s, %f, %n and %x, width and precision, flags, locales and the mistakes that throw exceptions.
By PC MomentUpdated 7 min read

Java’s printf lets you mix text and values in one line and control exactly how numbers look: decimal places, padding, alignment and thousands separators. You call it as System.out.printf(format, args...), where the format string holds placeholders like %d and %.2f.
The rules come from the java.util.Formatter class, and String.format uses the same syntax. Everything here matches the Java SE 25 documentation (Java 25 is the current LTS release, generally available since September 2025), and printf itself has existed since Java 5.
A first printf example
public class PrintfDemo {
public static void main(String[] args) {
String name = "Ana";
int items = 3;
double total = 42.5;
System.out.printf("%s bought %d items for $%.2f%n", name, items, total);
}
}
Output:
Ana bought 3 items for $42.50
Each % placeholder (a format specifier) is replaced by the next argument in order: %s by the string, %d by the integer and %.2f by the double with two decimal places. %n ends the line, because printf doesn’t add a newline on its own.
The rest of the snippets show only the statements. Put them inside a main method like the one above (and add import java.util.Locale; at the top of the file when a snippet uses Locale).
Note: Some output depends on your default locale (thousands separators and the decimal point). The examples assume an English (US) locale. See “Format for a specific Locale” below to make output predictable.
The format specifier syntax
Every specifier follows this pattern from the Formatter docs:
%[argument_index$][flags][width][.precision]conversion
Only % and the conversion character are required. The others are optional:
- argument_index$ picks which argument to use (
%2$sis the second). - flags change the output: left-align, zero-pad, add a sign or grouping separators.
- width is the minimum number of characters to write.
- precision is the number of digits after the decimal point for floating-point values, or the maximum number of characters for strings.
- conversion says how to format the argument (
d,s,fand so on).
Common conversions
| Specifier | Use it for | Example | Output |
|---|---|---|---|
%d | Integers (int, long, byte, short, BigInteger) | printf("%d", 42) | 42 |
%s | Any object, via toString() | printf("%s", "hello") | hello |
%S | Same, in upper case | printf("%S", "hello") | HELLO |
%f | float, double, BigDecimal | printf("%f", 3.14159) | 3.141590 |
%e | Scientific notation | printf("%e", 12345.678) | 1.234568e+04 |
%x / %X | Hexadecimal integer | printf("%x", 255) | ff |
%o | Octal integer | printf("%o", 8) | 10 |
%c | A character | printf("%c", 'A') | A |
%b | A boolean | printf("%b", true) | true |
%n | Platform line separator | printf("Hi%n") | Hi plus a line break |
%% | A literal percent sign | printf("%d%%", 75) | 75% |
A few details worth knowing:
%fand%eshow 6 decimal places by default, which is why3.14159prints as3.141590.%nproduces the line separator returned bySystem.lineSeparator(), so it’s the right choice for console output on any operating system.%sworks with any type, including numbers, because it callstoString(). If the argument isnull, it printsnull.
Width and alignment
Width sets the minimum number of characters. Values are right-aligned by default, and the - flag left-aligns them:
System.out.printf("[%8s]%n", "cat");
System.out.printf("[%-8s]%n", "cat");
System.out.printf("[%5d]%n", 42);
System.out.printf("[%05d]%n", 42);
System.out.printf("[%8.2f]%n", 3.14159);
Output:
[ cat]
[cat ]
[ 42]
[00042]
[ 3.14]
The brackets just show where the padding goes. The 0 flag pads numbers with leading zeros, and for negative numbers the zeros go after the sign, so %05d with -42 prints -0042.
Width is ideal for lining up columns:
String[] items = {"Keyboard", "Mouse", "Monitor"};
double[] prices = {49.99, 19.5, 189.0};
System.out.printf("%-10s %8s%n", "Item", "Price");
for (int i = 0; i < items.length; i++) {
System.out.printf("%-10s %8.2f%n", items[i], prices[i]);
}
Output:
Item Price
Keyboard 49.99
Mouse 19.50
Monitor 189.00
Precision: decimal places and string length
For floating-point conversions, precision is the number of digits after the decimal point:
System.out.printf("%.2f%n", 3.14159); // 3.14
System.out.printf("%.3f%n", Math.PI); // 3.142
System.out.printf("%.2f%n", 0.125); // 0.13
Java rounds with the half-up method, so 0.125 becomes 0.13. If you ask for more digits than the value has, zeros are added.
For strings, precision is the maximum number of characters, and it’s applied before the width:
System.out.printf("[%.3s]%n", "Hello"); // [Hel]
Important: Precision isn’t allowed with integer conversions.
%.2dthrows anIllegalFormatPrecisionException.
Flags
Flags go right after the % (or after the argument index):
| Flag | Effect | Example | Output |
|---|---|---|---|
- | Left-justify (needs a width) | printf("[%-6d]", 42) | [42 ] |
0 | Pad with zeros (needs a width) | printf("%05d", 42) | 00042 |
+ | Always show the sign | printf("%+d", 42) | +42 |
| space | Leading space for positive values | printf("% d", 42) | 42 |
, | Locale-specific grouping separators | printf("%,d", 1234567) | 1,234,567 |
( | Put negative numbers in parentheses | printf("%(d", -42) | (42) |
# | Alternate form, e.g. 0x for hex | printf("%#x", 255) | 0xff |
You can combine flags. %,.2f adds grouping and two decimals, so 1234567.891 prints as 1,234,567.89. The Formatter docs show %(,.2f turning a negative balance like -6217.58 into (6,217.58), a common style for accounting.
Some combinations aren’t allowed and throw an exception: - and 0 together, + and space together, and - or 0 without a width.
Reuse arguments with an index
By default, each specifier takes the next argument. Add n$ to choose one by position, or the < flag to reuse the previous argument:
System.out.printf("%1$s, %1$s, %2$s!%n", "go", "team"); // go, go, team!
System.out.printf("%s %<S%n", "hi"); // hi HI
If you pass more arguments than there are specifiers, the extra ones are ignored.
String.format and formatted()
When you need the formatted text as a String instead of printing it, use String.format. It takes the same format string and arguments:
String line = String.format("%s is %d years old", "Mia", 30);
System.out.println(line); // Mia is 30 years old
Since Java 15 you can also call formatted() on the format string itself. It’s equivalent to String.format(this, args):
String line = "%s is %d years old".formatted("Mia", 30);
Format for a specific Locale
Without a locale argument, printf and String.format use your default locale for formatting. That means the same code can print 1,234,567.89 on one computer and a different separator style on another. Pass a Locale as the first argument to control it:
System.out.printf(Locale.US, "%,.2f%n", 1234567.891); // 1,234,567.89
System.out.printf(Locale.FRANCE, "e = %+10.4f%n", Math.E); // e = +2,7183
The French example, taken from the Formatter docs, uses a comma as the decimal separator. Passing null as the locale means no localization is applied. Use an explicit locale whenever the output is read by another program, such as a CSV file.
Common printf mistakes
All of these throw a subclass of IllegalFormatException, an unchecked exception, so the compiler won’t warn you. You find out when the line runs.
Using %d with a double. printf("%d", 3.5) throws IllegalFormatConversionException, because %d only accepts integer types. Use %.0f, or cast the value to int first if you want to drop the decimals.
Using %f with an int. printf("%.2f", 5) throws the same exception. Pass 5.0, or cast: (double) count.
Too few arguments. printf("%s and %s%n", "one") throws MissingFormatArgumentException.
Using C habits like %i. Java has no %i conversion. It throws UnknownFormatConversionException. Use %d.
A stray percent sign. printf("50% off") treats % o as a specifier. Write %% for a literal percent: printf("50%% off%n").
Expecting %b to read a string. For anything that isn’t a boolean or Boolean, %b prints true unless the argument is null. So printf("%b", "false") prints true.
Forgetting %n. printf never adds a line break, so consecutive calls run together on one line. End the format string with %n.
Practice and next steps
The fastest way to learn the specifiers is to format a small table: a receipt, a list of scores, or a grade report with aligned columns. Change the widths and flags until it looks right.
Once your project grows, put it under version control. Our guide on git push set upstream covers pushing a new branch, and how to undo the last commit in git helps when you commit too early. If you also write Python, compare how it handles errors in our guide to raising exceptions in Python, and browse the Programming section for more beginner guides.
Frequently asked questions
What is the difference between printf and String.format in Java?
They use the same format syntax. System.out.printf writes the formatted text to the console, while String.format returns it as a String you can store or pass on.
Should I use %n or \n in Java printf?
Use %n. It produces the platform-specific line separator returned by System.lineSeparator(), so the line ending matches the operating system your program runs on.
How do I print a double with two decimal places in Java?
Use %.2f, for example System.out.printf("%.2f%n", 3.14159), which prints 3.14. Java rounds using the half-up method.
Why does printf throw IllegalFormatConversionException?
The conversion doesn't match the argument type, such as %d with a double or %f with an int. Use %f for floating-point values and %d for integer types.
How do I print a percent sign with printf?
Write %% in the format string. For example, printf("%d%%%n", 75) prints 75%.
Related guides

Programming
Python Raise Exception: How to Use raise, Custom Exceptions and raise from
How to raise exceptions in Python: built-in errors like ValueError, custom exception classes, raise from, re-raising and when to use assert instead.
7 min read

Programming
11 Python Projects for Beginners (With Starter Code)
Eleven small Python projects that teach real skills, from a number guessing game to a weather app, each with the modules it uses and starter code.
8 min read

Programming
How to Learn Python for Free: A Step-by-Step Path
A free path from zero to writing real Python: install it, pick one free course, use the official docs and build small projects.
7 min read

Programming
Git Undo Last Commit: Reset, Revert, Amend and How to Get It Back
Undo your last Git commit the right way: keep the changes, throw them away, or reverse a commit you already pushed, plus how to recover from a bad reset.
7 min read