ZetCode

Java Console - reading and writing to the console

last modified July 18, 2026

Java Console tutorial shows how to read input from and write output to the console using java.io.Console. The Console class provides methods for reading text and passwords, writing formatted output, and accessing the console's character stream.

Java Console

java.io.Console is a class that provides methods to access the character-based console device associated with the current Java virtual machine. It is obtained via the System.console() method.

Not all Java environments have a console. For instance, if the JVM is started from a background job scheduler or from within an IDE, the console may not be available. In such cases System.console() returns null. Always check for null before using the Console object.

Reading input with readLine

The readLine method reads a single line of text from the console. It returns the line as a String, or null if the end of the input stream has been reached.

Main.java
void main() {

    var console = System.console();

    if (console == null) {
        System.out.println("No console available");
        return;
    }

    var name = console.readLine("Enter your name: ");
    console.printf("Hello, %s!%n", name);
}

We obtain the console via System.console() and check that it is not null. The readLine method displays a prompt and waits for user input. The entered text is returned and then printed back with a greeting.

$ java Main.java
Enter your name: John
Hello, John!

Reading passwords with readPassword

The readPassword method reads a password or passphrase with echoing disabled. It returns a char[] instead of a String to minimize the lifetime of sensitive data in memory. After processing, the array should be manually zeroed.

Main.java
void main() {

    var console = System.console();

    if (console == null) {
        System.out.println("No console available");
        return;
    }

    var user = console.readLine("Username: ");
    var passwd = console.readPassword("Password: ");

    if (passwd != null) {

        var input = new String(passwd);

        if ("admin".equals(user) && "s3cret".equals(input)) {
            console.printf("Welcome, %s!%n", user);
        } else {
            console.printf("Invalid credentials%n");
        }

        Arrays.fill(passwd, ' ');
    }
}

The password is read as a character array with echoing disabled, preventing the password from being visible on screen. We convert the character array to a String for comparison against stored credentials. After processing, the array is zeroed with Arrays.fill to minimize the lifetime of sensitive data in memory.

$ java Main.java
Username: admin
Password:
Welcome, admin!

Formatted output with format and printf

The format and printf methods write formatted strings to the console. They work like System.out.printf but return the Console instance, enabling method chaining.

Main.java
void main() {

    var console = System.console();

    if (console == null) {
        System.out.println("No console available");
        return;
    }

    console.format("Name: %s, Age: %d%n", "John Doe", 34)
           .format("Salary: $%.2f%n", 45600.50)
           .format("Active: %b%n", true);
}

Console.format returns the console instance, allowing us to chain multiple format calls. The format string syntax is the same as String.format. The printf method is an alias for format.

$ java Main.java
Name: John Doe, Age: 34
Salary: $45600.50
Active: true

Using the writer

The writer method returns the PrintWriter associated with the console. This can be used for general-purpose text output.

Main.java
void main() {

    var console = System.console();

    if (console == null) {
        System.out.println("No console available");
        return;
    }

    var writer = console.writer();

    writer.println("Console output via PrintWriter");
    writer.println("Line 2");
    writer.printf("PI: %.5f%n", Math.PI);
    writer.flush();
}

The writer gives access to the underlying PrintWriter stream. Calling flush forces any buffered output to be written immediately.

$ java Main.java
Console output via PrintWriter
Line 2
PI: 3.14159

Using the reader with Scanner

The reader method returns the Reader associated with the console. This is intended for sophisticated applications, such as wrapping the console input in a Scanner for rich parsing capabilities.

Main.java
void main() {

    var console = System.console();

    if (console == null) {
        System.out.println("No console available");
        return;
    }

    try (var scanner = new Scanner(console.reader())) {

        var name = scanner.nextLine();
        var age = scanner.nextInt();
        var salary = scanner.nextDouble();

        console.format("%s is %d years old and earns $%.2f%n",
                name, age, salary);
    }
}

We create a Scanner from the console's Reader. This allows us to parse typed input such as integers and doubles directly from the console without manual conversion.

$ java Main.java
Jane Smith
28
52000.00
Jane Smith is 28 years old and earns $52000.00

The charset method

The charset method returns the Charset used for write operations on this console. The charset is based on the stdout.encoding system property and may differ from the default charset.

Main.java
void main() {

    var console = System.console();

    if (console == null) {
        System.out.println("No console available");
        return;
    }

    var charset = console.charset();
    console.format("Console charset: %s%n", charset);
    console.format("Default charset: %s%n",
            java.nio.charset.Charset.defaultCharset());
}

The charset method returns the encoding used for console output. On most modern systems this is typically UTF-8.

$ java Main.java
Console charset: UTF-8
Default charset: UTF-8

The isTerminal method

The isTerminal method (added in Java 22) returns true if the console is connected to an interactive terminal. This can be used to adapt program behavior depending on whether the input/output is a terminal or a pipe.

Colorized vs plain output

When output is sent to a terminal, we can use ANSI escape codes to add color. When piped to another program, the codes are stripped to keep the output clean.

Main.java
void main() {

    var console = System.console();

    if (console == null) {
        System.out.println("No console available");
        return;
    }

    var color = console.isTerminal();

    var green = color ? "\u001b[32;1m" : "";
    var red = color ? "\u001b[31;1m" : "";
    var reset = color ? "\u001b[0m" : "";

    console.format("%sOK%s   Server is running%n", green, reset);
    console.format("%sERR%s  Connection refused%n", red, reset);
}

We check isTerminal to decide whether ANSI escape codes should be included in the output. In a terminal, OK appears in green bold and ERR in red bold.

Note that when the output is piped, System.console() returns null and the program exits before reaching the isTerminal check. This is a typical pattern: console-aware code handles the interactive case and gracefully exits when no console is available.

$ java Main.java
OK   Server is running
ERR  Connection refused

Interactive confirmation vs silent mode

When running interactively, the program asks for confirmation before proceeding. When piped, it skips the prompt and uses a default behavior.

Main.java
void main() {

    var console = System.console();

    if (console == null) {
        System.out.println("No console available");
        return;
    }

    if (console.isTerminal()) {

        var reply = console.readLine("Delete all files? (y/n): ");

        if (!"y".equals(reply)) {
            console.format("Aborted%n");
            return;
        }
    }

    console.format("Deleting files...%n");
}

In an interactive terminal, the user is prompted to confirm the operation. In a non-interactive setting, System.console() returns null and the program exits before a destructive operation could proceed — adding a layer of safety for scripted invocations.

$ java Main.java
Delete all files? (y/n): n
Aborted

$ java Main.java
Delete all files? (y/n): y
Deleting files...

Console vs Scanner — when to use which

Both Console and Scanner can read user input, but they serve different purposes.

Feature Console Scanner
Secure password input Yes — readPassword disables echoing No
Formatted output Yes — format, printf with chaining No (use System.out.printf)
Typed parsing (int, double) Via reader() wrapped in Scanner Native — nextInt, nextDouble
Custom delimiters No Yes — useDelimiter
Token streams No Yes — tokens() method
File input No Yes — new Scanner(Path)
String input No Yes — new Scanner(String)
Finding patterns No Yes — findInLine, skip
Prompt support Built-in — readLine("prompt") Manual — System.out.print
Locale-aware parsing Via format(locale, ...) Yes — useLocale
Availability Only in interactive terminal — may be null Always available

Use Console when you need password input without echoing, prompt-based formatted output, or chained formatting. The readPassword method is the only standard way to read passwords securely in Java.

Use Scanner when parsing mixed data types (numbers, booleans, tokens), reading from files or strings, using custom delimiters, or processing token streams with the functional tokens() API. Scanner also supports locale-aware parsing for decimal number formats in different regions.

The two can be combined: wrap Console.reader() in a Scanner for the best of both worlds — prompt support from Console and type-safe parsing from Scanner.

Source

Java Console - language reference

In this article we have used Java's Console class to read input from and write output to the terminal.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Java tutorials.