How to print in Java?

Back to Blog

How to print in Java?

Understanding Java Print Methods

Printing output is one of the first concepts you learn when studying Java. Whether you are displaying results to the console, logging debug information, or providing user feedback, knowing how to print effectively is essential. Java provides several methods through the System class that handle output in different ways, each suited for specific situations.

The most common way to send output to the console is through the System.out object, which represents the standard output stream. However, Java gives you multiple options beyond the basic println() method, and understanding each one helps you write more effective and maintainable code.

System.out.println() vs System.out.print() vs System.out.printf()

These three methods are the primary tools for printing in Java, and they each serve different purposes. The key differences lie in how they handle strings, newline characters, and formatting.

System.out.println() prints the provided argument and automatically adds a newline character at the end. This means each call moves the cursor to the next line.

System.out.println("Hello, World!");
System.out.println("This is on a new line");

Output:

Hello, World!
This is on a new line

System.out.print() outputs the argument but does not add a newline. Multiple print statements on successive lines will produce output on the same line in the console.

System.out.print("Hello");
System.out.print(" ");
System.out.print("World!");

Output:

Hello World!

System.out.printf() allows formatted output with format specifiers, similar to C’s printf function. You provide a format string and arguments that fill in the placeholders.

int age = 25;
String name = "Alice";
System.out.printf("Name: %s, Age: %d%n", name, age);

Output:

Name: Alice, Age: 25

Printing Different Data Types

Java’s print methods work with all primitive and object types. The key is understanding how each type is converted to a string representation.

Integers print as expected without any special handling:

int count = 42;
System.out.println(count);  // Output: 42

Floating-point numbers print with decimal representation:

double price = 19.99;
System.out.println(price);  // Output: 19.99

Strings print as literal characters:

String message = "Java is powerful";
System.out.println(message);  // Output: Java is powerful

Boolean values print as “true” or “false”:

boolean isActive = true;
System.out.println(isActive);  // Output: true

Characters print as single characters:

char letter = 'J';
System.out.println(letter);  // Output: J

When you print an array directly, you get a memory reference rather than the contents:

int[] numbers = {1, 2, 3};
System.out.println(numbers);  // Output: [I@1f32e575 (memory address)

Formatted Output with printf and String.format

For precise control over how values appear, printf() and String.format() give you powerful formatting capabilities. Format specifiers tell Java how to convert and display values.

The %d specifier handles integers:

int score = 95;
System.out.printf("Score: %d%n", score);  // Output: Score: 95

The %f specifier handles floating-point numbers with configurable decimal places:

double temperature = 98.6;
System.out.printf("Temperature: %.1f degrees%n", temperature);  // Output: Temperature: 98.6 degrees

The %.2f variant shows exactly two decimal places:

double amount = 150;
System.out.printf("Amount: $%.2f%n", amount);  // Output: Amount: $150.00

The %s specifier handles strings:

String fruit = "apple";
System.out.printf("Favorite fruit: %s%n", fruit);  // Output: Favorite fruit: apple

The %n specifier produces a newline, which is platform-independent and preferred over hardcoded
in printf:

System.out.printf("Line 1%nLine 2%n");
// Output:
// Line 1
// Line 2

The %c specifier prints characters:

char initial = 'J';
System.out.printf("Initial: %c%n", initial);  // Output: Initial: J

The %b specifier prints boolean values:

boolean valid = true;
System.out.printf("Valid: %b%n", valid);  // Output: Valid: true

You can control width and padding. This right-aligns a number in a field 5 characters wide:

int id = 7;
System.out.printf("ID: %5d%n", id);  // Output: ID:     7

Left-aligning uses a minus sign:

int id = 7;
System.out.printf("ID: %-5d%n", id);  // Output: ID: 7    

Padding with zeros works for numbers:

int code = 42;
System.out.printf("Code: %05d%n", code);  // Output: Code: 00042

String.format() creates a formatted string without printing it immediately, which is useful when you need to store or manipulate the formatted result:

String result = String.format("Value: %d", 100);
System.out.println(result);  // Output: Value: 100

Printing to stderr with System.err.println()

While System.out is standard output, System.err is standard error. Error messages and warnings should go to System.err, which allows scripts and tools to separate normal output from errors.

System.err.println("An error occurred!");
System.err.printf("Error code: %d%n", 404);

From the program’s perspective, both work identically. The difference matters when output is redirected in the shell or captured by another program.

Logging vs Printing

For production applications, logging frameworks like Log4j or SLF4J are preferable to direct printing. Logging offers timestamps, severity levels, and file rotation that System.out does not provide. However, for simple scripts, learning applications, and quick debugging, direct printing is appropriate.

Use System.out.println() for educational examples and small tools. Use a logging framework for anything that runs in production. This separation makes code more professional and maintainable as applications grow.

Printing Arrays

Printing an array directly shows a memory reference. To display the actual contents, use Arrays.toString():

import java.util.Arrays;

int[] scores = {85, 90, 78};
System.out.println(Arrays.toString(scores));  // Output: [85, 90, 78]

For two-dimensional arrays, use Arrays.deepToString():

int[][] matrix = {{1, 2}, {3, 4}};
System.out.println(Arrays.deepToString(matrix));  // Output: [[1, 2], [3, 4]]

You can also iterate and print each element individually for custom formatting:

int[] numbers = {10, 20, 30};
for (int num : numbers) {
    System.out.println(num);
}

Printing Collections

ArrayList and other collections print nicely by default because they override the toString() method:

import java.util.ArrayList;

ArrayList fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
System.out.println(fruits);  // Output: [apple, banana]

This works for any List, Set, Map, and other standard collections without extra work.

Custom toString() Method on Objects

When you print a custom object, Java calls its toString() method. By default, this returns a memory reference. Override toString() to provide meaningful output:

class Person {
    String name;
    int age;
    
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

Person p = new Person("Bob", 30);
System.out.println(p);  // Output: Person{name='Bob', age=30}

A well-implemented toString() makes debugging and logging much easier.

Unicode and Special Characters

Java handles Unicode natively, so you can print characters from any language:

System.out.println("Hello 世界");  // Output: Hello 世界
System.out.println("Résumé");  // Output: Résumé

Special characters use escape sequences:

System.out.println("Quote: "Hello"");  // Output: Quote: "Hello"
System.out.println("Backslash: \");  // Output: Backslash: System.out.println("Tab:	Spaced");  // Output: Tab:    Spaced

Newline Characters

The newline character
moves the cursor to the next line. On Windows, the system line separator is
, but using
works everywhere because Java handles it correctly:

System.out.println("Line 1
Line 2");
// Output:
// Line 1
// Line 2

For truly platform-independent code, use System.lineSeparator():

System.out.println("Line 1" + System.lineSeparator() + "Line 2");

The %n format specifier in printf() automatically uses the correct line separator for the current platform.

Common Printing Mistakes

Printing null values does not cause an error but produces the string “null”:

String text = null;
System.out.println(text);  // Output: null

This can hide bugs, so always check for null before printing sensitive values:

String text = null;
System.out.println(text != null ? text : "No value provided");

Using the wrong format specifier produces unexpected output or an exception:

System.out.printf("Value: %d%n", "text");  // Exception: invalid format specifier

Forgetting %n in printf leaves no newline and output runs together:

System.out.printf("Line 1");
System.out.printf("Line 2");
// Output: Line 1Line 2 (no newline between them)

Best Practices for Printing

Use println() for most printing tasks because it automatically adds newlines. Use print() only when you specifically need to avoid a newline. Use printf() when you need precise formatting, especially for numbers and currency.

For applications with persistent output requirements, consider structured logging rather than direct console printing. Always validate input before printing to avoid exposing sensitive information or null values unexpectedly.

Understanding the fundamentals of Java print methods gives you confidence in handling output across various scenarios, from simple educational programs to complex applications.

Share this post

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Blog