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

SpecifierUseExample
%sString"hello"
%dInteger42
%fFloating-point3.141593
%eScientific notation3.141593e+00
%x / %XHexadecimalff / FF
%oOctal777
%bBooleantrue
%cCharacterA
%%Literal %%
%nLine 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 β€” %d with 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

  • println prints and appends a newline. Simple, no formatting.
  • print prints without newline.
  • printf prints 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.