Console Output
Java writes to the terminal through System.out and System.err, with print/println for simple output and printf/String.format for precise, formatted results.
Producing console output is one of the first things any Java program does, and Java offers several layers of control: simple unformatted printing with print()/println(), separating error output with System.err, and precise, formatted output with printf() and String.format() using C-style format specifiers.
System.out and System.err
System.out is a PrintStream connected to standard output (stdout) — the normal channel for a program's ordinary output. System.err is a separate PrintStream connected to standard error (stderr), conventionally used for error messages and diagnostics. Keeping them separate lets users (or shell scripts) redirect ordinary output and error output to different destinations.
stdout and stderr are usually both shown together in an interactive terminal, so the distinction is easy to miss during casual development — it matters most when output is redirected or piped, e.g. java MyApp > output.txt only captures stdout.
System.out.println("Processing started.");
System.err.println("Warning: config file not found, using defaults.");print() vs println()
print() writes its argument with no trailing newline; println() writes the argument followed by a line separator, moving subsequent output to a new line.
System.out.print("Hello, ");
System.out.print("world");
System.out.println(); // just a newline
System.out.println("Done.");
// Output:
// Hello, world
// Done.Both Methods Accept Many Types
print()/println() are overloaded for every primitive type, char[], String, and Object — for an Object argument, they call the object's toString() method (Object.toString() by default, or an overridden version if the class provides one).
System.out.println(42); // int overload
System.out.println(3.14); // double overload
System.out.println(true); // boolean overload
System.out.println('A'); // char overload
System.out.println((Object) 42); // calls toString() on the boxed Integerprintf() and Formatted Output
printf() writes output built from a format string containing format specifiers (placeholders starting with %) plus a matching list of arguments, similar in spirit to C's printf. It gives precise control over how numbers, strings, and other values are rendered — field width, decimal precision, padding, and more.
double price = 19.999;
System.out.printf("Price: $%.2f%n", price); // Price: $20.00
System.out.printf("%-10s|%5d%n", "item", 3); // item | 3Common Format Specifiers
Format specifiers combine a conversion character (what type/format to use) with optional flags for width, precision, and alignment.
%d - integer (decimal)
%f - floating-point (fixed notation)
%s - String (calls toString() on non-String arguments)
%c - character
%b - boolean
%x - integer in hexadecimal
%% - a literal percent sign
%n - platform-specific line separator (preferred over \n for portability)
Flags/width/precision examples:
%5d - pad to width 5, right-aligned
%-5d - pad to width 5, left-aligned
%.2f - 2 digits after the decimal point
%,d - group digits with locale-appropriate separators (e.g. 1,000,000)String.format(): Formatting Without Printing
String.format() takes the exact same format-string-plus-arguments approach as printf(), but returns the formatted result as a String instead of writing it to a stream. This is useful whenever you need the formatted text for something other than immediate console output — building a message, logging, constructing UI text.
System.out.printf(fmt, args) is essentially equivalent to System.out.print(String.format(fmt, args)) — printf is a convenience that formats and writes in one call.
String message = String.format("User %s has %d points.", "Ada", 150);
System.out.println(message); // User Ada has 150 points.Formatting Numbers Precisely
Precision and width flags are especially useful for tabular output and monetary/scientific values.
System.out.printf("%8.2f%n", 3.14159); // " 3.14" (width 8, 2 decimals)
System.out.printf("%,d%n", 1234567); // "1,234,567"
System.out.printf("%05d%n", 42); // "00042" (zero-padded width 5)Practical Usage: Tabular Output
Combining width and alignment flags is the standard way to print aligned tables to the console without a UI library.
String[] names = {"Ada", "Grace", "Alan"};
int[] scores = {95, 88, 91};
for (int i = 0; i < names.length; i++) {
System.out.printf("%-10s%5d%n", names[i], scores[i]);
}
// Ada 95
// Grace 88
// Alan 91Basic Output Conventions
A few habits keep console output clean and portable: prefer %n over the literal \n inside format strings, since %n resolves to the platform's actual line separator (println() handles this automatically, but printf()/format() do not unless you use %n explicitly); route genuine errors and diagnostics to System.err rather than System.out so they can be filtered separately; and avoid leaving debug System.out.println() calls scattered through production code — use a proper logging framework there instead (covered in its own topic).
System.out.printf("Value: %d\n", 5); // works, but \n is not guaranteed portable across platforms
System.out.printf("Value: %d%n", 5); // preferred: %n adapts to the platform's line separatorComplete Example
public class OutputDemo {
public static void main(String[] args) {
String name = "Ada Lovelace";
int age = 36;
double gpa = 3.987;
System.out.println("=== Student Report ===");
System.out.printf("Name : %s%n", name);
System.out.printf("Age : %d%n", age);
System.out.printf("GPA : %.2f%n", gpa);
if (gpa < 2.0) {
System.err.println("Warning: GPA below minimum threshold.");
}
String summary = String.format("%s (age %d) has GPA %.2f", name, age, gpa);
System.out.println(summary);
}
}Quick Reference
System.out.print(x) - write x, no newline
System.out.println(x) - write x, then a newline
System.err.println(x) - write x to the error stream
System.out.printf(fmt, args...) - formatted write, no automatic newline
String.format(fmt, args...) - build a formatted String (no output)
%d %f %s %c %b %x %% %n - common conversion specifiers
%-10s / %5d / %.2f / %,d / %05d - alignment, width, precision, grouping, zero-padKey Takeaways
System.out is standard output; System.err is standard error — keep error/diagnostic messages on System.err.
print() writes with no newline; println() appends one automatically.
printf() and String.format() share the same format-specifier syntax; printf() writes immediately, String.format() returns a String.
%n is the portable line separator for format strings; \n is not guaranteed to match the platform.
Width, precision, alignment, and grouping flags on format specifiers give fine control over numeric and tabular output.
System.out.printf("Total: %d\n", total);
System.out.printf("Total: %d%n", total);
%n resolves to the platform-appropriate line separator inside a format string; a literal \n is not guaranteed to be portable across all platforms.
System.out.println("Error: file not found");
System.err.println("Error: file not found");
Error and diagnostic messages belong on System.err, not System.out, so they can be distinguished and redirected separately from normal output.
System.out.printf("%.2d%n", 42); // trying to format an int with a float-style precision
System.out.printf("%5d%n", 42); // or %05d for zero-padding %d does not accept a precision flag the way %f does — precision on integers throws IllegalFormatPrecisionException. Use width/zero-pad flags for integers instead.
What is the difference between System.out and System.err, and why does the distinction matter?
System.out is the standard output stream for ordinary program output; System.err is the standard error stream for diagnostics/errors. They can be redirected independently by the shell (e.g. prog > out.txt 2> err.txt), so keeping errors on System.err lets normal output and error messages be separated even though both appear together in an interactive terminal.
What is the difference between print() and println()?
print() writes its argument with no trailing line separator; println() writes the argument and then appends a line separator, so the next output starts on a new line.
Why is %n generally preferred over \n inside a printf()/String.format() format string?
%n is translated to the actual platform-specific line separator at format time, making output portable; \n is a literal newline character which is not guaranteed to match every platform's convention.
What is the difference between printf() and String.format(), given they use the same format syntax?
printf() formats the arguments and writes the result directly to the stream it's called on (e.g. System.out). String.format() performs the same formatting but returns the result as a String instead of writing it anywhere.
What does the format specifier %-10s do?
It formats a String argument, left-aligned, padded with spaces to a minimum field width of 10 characters.
If an Object (not a String) is passed as the argument for a %s specifier, what does printf() do with it?
It calls the object's toString() method (Object's default or an overridden version) to obtain the text to insert.
Why might scattering System.out.println() calls throughout production code be considered a poor practice?
Println output can't be leveled (info/warn/error), filtered, redirected to files, or turned off selectively at runtime the way a proper logging framework's calls can — println calls tend to accumulate as ad hoc debug noise that's easy to forget and hard to control in production.
Write code that prints a right-aligned table of three items and their prices, each price formatted to 2 decimal places and aligned in a column of width 8.
String[] items = {"Pen", "Notebook", "Eraser"}; double[] prices = {1.5, 4.2, 0.75}; for (int i = 0; i < items.length; i++) { System.out.printf("%-10s%8.2f%n", items[i], prices[i]); }
%-10s left-aligns the item name in a 10-character field, and %8.2f right-aligns the price in an 8-character field with exactly 2 decimal digits, producing a neatly aligned table.
What does this code print, line by line?
It prints two lines: "ABC" then "D". print() has no trailing newline so A, B, and C run together on one line; println("C") then adds the newline, and println("D") prints D on its own line.
Write a method that formats a name and a whole-number score into a fixed-width String (not printed, just returned) using String.format, suitable for later logging.
static String formatEntry(String name, int score) { return String.format("%-15s%5d", name, score); }
String.format applies the same width/alignment specifiers as printf but returns the text as a String instead of writing it to a stream, so it can be stored, logged, or displayed elsewhere.
System.out.print("A");
System.out.print("B");
System.out.println("C");
System.out.println("D");