Print Variables
In short: Printing variable values to the console — usually with System.out.println(variable) or formatted with System.out.printf(...).
In more detail: println implicitly calls toString() on the value passed — for custom classes with no overridden toString() method, this only returns a not very helpful default output like Car@1a2b3c. printf allows formatting with placeholders, e.g. System.out.printf("Price: %.2f%n", price); for two decimal places.
In Depth
int age = 25;
double price = 19.5;
System.out.println(age); // "25"
System.out.println("Age: " + age); // "Age: 25" - concatenation with +
System.out.printf("Price: %.2f%n", price); // "Price: 19.50" - formatted
// Text blocks (since Java 15) for multi-line output
System.out.println("""
Name: Anna
Age: %d
""".formatted(age));
class Car {
String color = "Blue";
@Override
public String toString() { return "Car[color=" + color + "]"; } // define custom output
}
System.out.println(new Car()); // "Car[color=Blue]" - without toString(): "Car@1a2b3c" (hash code)println implicitly calls .toString() for every non-string argument — for custom classes, Java’s automatically generated default implementation only returns the class name plus a not very meaningful hash code identifier (Car@1a2b3c), as long as you don’t override toString() yourself. For debugging purposes, a custom toString() implementation is therefore very valuable: System.out.println(car) then immediately shows the relevant field values instead of a meaningless memory address. printf with %.2f (two decimal places), %d (integer), %s (string), and %n (platform-independent line break, better than \n) offers finer control over the output format than pure string concatenation.
print vs. println vs. printf
Three closely related but different output methods: print() prints WITHOUT a line break afterwards, println() automatically appends a line break, printf() allows formatted output via placeholders, but itself outputs NO automatic line break (%n has to be specified explicitly):
System.out.print("Value: "); // no line break afterwards
System.out.println(42); // "Value: 42", THEN a line break
System.out.printf("%s is %d years old%n", "Anna", 25); // own %n neededString.format() — the same formatting without direct output
String.format() uses exactly the same placeholder syntax as printf, but returns the result as a String instead of writing it directly to the console — useful when the formatted text is meant to be further processed, written to a file, or displayed in a GUI, instead of landing directly on stdout:
String message = String.format("Price: %.2f€ (%d items)", 19.99, 3);
// message now contains "Price: 19.99€ (3 items)", not yet outputSystem.err — error output separate from normal output
Besides System.out, there’s System.err for error messages — both land on the console by default, but are technically separate streams that can be redirected independently of each other (e.g. program > log.txt 2> error.txt on the command line separates normal output from error messages into two files).
See also: Statements, Strings, String Concatenation