Displaying Text with the printf Method in Java
System.out.printf is Java's formatted-output method, inspired directly by C's printf. It gives you precise control over how numbers, strings and dates are rendered β padding, alignment, precision, thousand separators and more.
The basics
The method takes a format string and a variable number of arguments. % introduces a conversion specifier that is replaced by the next argument, formatted according to the rules that follow %.
System.out.printf("Hello, %s!%n", "world"); // Hello, world!
System.out.printf("Age: %d%n", 30); // Age: 30
System.out.printf("Pi: %.3f%n", Math.PI); // Pi: 3.142
System.out.printf("%s is %d years old%n", "Alice", 30);
%n is the platform-specific line separator (LF on Linux/macOS, CRLF on Windows). Use it instead of \n for portable output.
Common conversion specifiers
| Specifier | Use | Example |
|---|---|---|
%s | String | "hello" |
%d | Integer | 42 |
%f | Floating-point | 3.141593 |
%e | Scientific notation | 3.141593e+00 |
%x / %X | Hexadecimal | ff / FF |
%o | Octal | 777 |
%b | Boolean | true |
%c | Character | A |
%% | Literal % | % |
%n | Line separator | \n or \r\n |
Width, precision and flags
The full syntax is:
%[flags][width][.precision]conversion
Padding and alignment
System.out.printf("[%5d]%n", 42); // [ 42] right-aligned, width 5
System.out.printf("[%-5d]%n", 42); // [42 ] left-aligned
System.out.printf("[%05d]%n", 42); // [00042] padded with zeros
Precision for floats
System.out.printf("%.2f%n", Math.PI); // 3.14
System.out.printf("%10.4f%n", Math.PI); // " 3.1416"
System.out.printf("%-10.4f|%n", Math.PI);// "3.1416 |"
Thousand separator
System.out.printf("%,d%n", 1_000_000); // 1,000,000 (locale-dependent)
Plus sign for positive numbers
System.out.printf("%+d%n", 42); // +42
System.out.printf("%+d%n", -5); // -5
Formatting dates
Via the %t conversion, with a sub-specifier:
import java.util.Calendar;
Calendar c = Calendar.getInstance();
System.out.printf("%tF%n", c); // 2026-04-20 (ISO date)
System.out.printf("%tT%n", c); // 14:35:12 (ISO time)
System.out.printf("%tA %td %tB %tY%n", c, c, c, c);
// Monday 20 April 2026
Since Java 8, you are better off formatting with DateTimeFormatter and passing a plain string to printf via %s:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
String formatted = LocalDate.now().format(DateTimeFormatter.ISO_DATE);
System.out.printf("Date: %s%n", formatted);
Argument reuse with %n$
System.out.printf("%1$s, %1$s and %2$s%n", "one", "two");
// one, one and two
Locale awareness
Without a specified locale, printf uses Locale.getDefault(Locale.Category.FORMAT), which means the thousand separator, decimal separator or month names vary between machines. For deterministic output (logs, data files), pass a locale explicitly:
import java.util.Locale;
System.out.printf(Locale.FRANCE, "%.2f%n", 1234.5); // 1234,50
System.out.printf(Locale.US, "%.2f%n", 1234.5); // 1234.50
System.out.printf(Locale.ROOT, "%.2f%n", 1234.5); // 1234.50 (stable)
Use Locale.ROOT when you want neutral, machine-readable output.
Returning a formatted string: String.format
Same syntax, returns a String instead of writing to stdout:
String line = String.format("User %s has %d points (%.1f%%)", "Alice", 847, 84.7);
// "User Alice has 847 points (84.7%)"
Internally, printf calls String.format then writes the result. Pick whichever fits the call site.
Format exceptions
Wrong number or type of arguments throws at runtime:
MissingFormatArgumentExceptionβ fewer args than%specifiers.IllegalFormatConversionExceptionβ%dwith a String argument.UnknownFormatConversionExceptionβ typo in specifier, e.g.%q.
These are runtime errors. Consider static-analysis tools (SpotBugs, ErrorProne) that check printf format strings at compile time β they catch the vast majority of these mistakes before deployment.
printf versus println
printlnprints and appends a newline. Simple, no formatting.printprints without newline.printfprints formatted output, no automatic newline β use%n.
For modern Java, consider String::formatted (Java 15+) as a fluent alternative:
String msg = "Hello %s, you are %d".formatted("Alice", 30);
Whichever you pick, printf-style formatting remains one of the most useful tools in your Java toolbox β for logs, reports and any human-readable output.