Home Java Java Input and Output Explained — Scanner, System.out and Real Examples

Java Input and Output Explained — Scanner, System.out and Real Examples

In Plain English 🔥
Think of your Java program as a chef in a kitchen. Input is the customer's order — information coming IN to the chef so they know what to cook. Output is the finished meal placed on the table — information going OUT from the chef back to the customer. Just like a restaurant needs a system for taking orders and serving food, Java needs a system for reading data and printing results. That system is what Input and Output (I/O) is all about.
⚡ Quick Answer
Think of your Java program as a chef in a kitchen. Input is the customer's order — information coming IN to the chef so they know what to cook. Output is the finished meal placed on the table — information going OUT from the chef back to the customer. Just like a restaurant needs a system for taking orders and serving food, Java needs a system for reading data and printing results. That system is what Input and Output (I/O) is all about.

Every useful program in the world does at least one of two things: it takes information in, or it sends information out. Your phone's calculator takes in numbers you tap and outputs an answer. A login screen takes in your password and outputs either a welcome screen or an error. Without input and output, a program just runs silently in a box and does nothing anyone can see. That's why I/O is the very first real-world skill you need as a Java developer — it's how your program talks to the outside world.

Printing to the Console — Java's Built-In Megaphone

Before your program can accept input, it needs to be able to speak. Printing to the console is Java's way of shouting a message to whoever is running the program. Think of it like a scoreboard at a sports game — it's how the program announces what's happening.

Java gives you three closely related tools for this, and beginners often use them interchangeably without understanding the differences. System.out.println() prints your message and then moves the cursor to a new line — like pressing Enter after typing. System.out.print() prints your message but stays on the same line, so the next thing printed appears right next to it. System.out.printf() is the most powerful — it lets you format your output precisely, like lining up numbers in a table.

System is a built-in Java class that represents your computer's environment. out is the output stream attached to your console. And println, print, and printf are the methods you call on it. You don't need to import anything — Java includes System automatically in every program.

PrintingExamples.java · JAVA
123456789101112131415161718192021222324252627
public class PrintingExamples {
    public static void main(String[] args) {

        // println adds a newline after printing — cursor moves to the next line
        System.out.println("Welcome to TheCodeForge!");

        // print does NOT add a newline — the next output continues on the same line
        System.out.print("First name: ");
        System.out.print("Ada ");
        System.out.print("Lovelace");

        // We need a manual newline here to move to the next line
        System.out.println(); // prints an empty line

        // printf lets you format values inline using format specifiers
        // %s = String placeholder, %d = integer placeholder, %n = newline
        String productName = "Java Book";
        int quantityInStock = 42;
        double priceInDollars = 29.99;

        System.out.printf("Product : %s%n", productName);
        System.out.printf("In Stock : %d units%n", quantityInStock);

        // %.2f means: print a floating-point number with exactly 2 decimal places
        System.out.printf("Price    : $%.2f%n", priceInDollars);
    }
}
▶ Output
Welcome to TheCodeForge!
First name: Ada Lovelace
Product : Java Book
In Stock : 42 units
Price : $29.99
⚠️
Pro Tip: Prefer printf for Formatted DataAny time you're printing a receipt, a table, or a report, reach for printf. It keeps your alignment clean and your code readable. Using string concatenation with + for formatted numbers is fragile and hard to read.

Reading User Input with Scanner — Java's Ears

Printing is only half the story. A program that can't accept input is like a vending machine with no buttons — it just sits there. Java's Scanner class is your go-to tool for reading what a user types into the console.

Scanner lives in the java.util package, so you must import it at the top of your file before you can use it. You create one Scanner object and keep it for the whole program — creating a new Scanner every time you want to read input is wasteful and causes bugs.

Once you have a Scanner, you call different methods depending on what type of data you're expecting. nextLine() reads a whole line of text including spaces. next() reads only one word (stops at a space). nextInt() reads an integer. nextDouble() reads a decimal number. The Scanner pauses the program and waits for the user to type something and press Enter — that pause is called blocking, and it's intentional.

Always close your Scanner when you're done using it. It's connected to a resource (the keyboard input stream), and leaving it open is a memory leak waiting to happen.

UserProfileInput.java · JAVA
12345678910111213141516171819202122232425262728293031323334
import java.util.Scanner; // We MUST import Scanner before using it

public class UserProfileInput {
    public static void main(String[] args) {

        // System.in is the keyboard input stream — we wrap it in Scanner to read it easily
        Scanner keyboardInput = new Scanner(System.in);

        // Prompt the user — always print a message BEFORE reading input
        System.out.print("Enter your full name: ");

        // nextLine() reads everything the user types until they press Enter
        String fullName = keyboardInput.nextLine();

        System.out.print("Enter your age: ");

        // nextInt() reads a whole number — it will crash if the user types letters!
        int userAge = keyboardInput.nextInt();

        System.out.print("Enter your account balance: ");

        // nextDouble() reads a decimal number like 1250.75
        double accountBalance = keyboardInput.nextDouble();

        // Print a formatted summary back to the user
        System.out.println("\n--- Profile Summary ---");
        System.out.printf("Name    : %s%n", fullName);
        System.out.printf("Age     : %d years old%n", userAge);
        System.out.printf("Balance : $%.2f%n", accountBalance);

        // Close the Scanner to release the keyboard resource
        keyboardInput.close();
    }
}
▶ Output
Enter your full name: Marie Curie
Enter your age: 35
Enter your account balance: 4820.50

--- Profile Summary ---
Name : Marie Curie
Age : 35 years old
Balance : $4820.50
⚠️
Watch Out: The nextInt() + nextLine() TrapIf you call nextInt() and then nextLine() immediately after, the nextLine() will return an empty string. Why? nextInt() reads the number but leaves the newline character (Enter key) in the buffer. The nextLine() then instantly consumes that leftover newline. Fix: add an extra keyboardInput.nextLine() after nextInt() to flush the buffer before reading a string.

Handling the nextInt/nextLine Bug and Input Validation

This bug trips up almost every beginner, so it deserves its own section. When you mix nextInt() or nextDouble() with nextLine(), the Scanner's internal buffer causes a silent but nasty problem. Let's look at exactly what happens and how to fix it cleanly.

Imagine the user types 25 and presses Enter. What's actually in the buffer is 25 . When you call nextInt(), it reads 25 but leaves the sitting in the buffer. The very next nextLine() sees that and says 'I found a newline — my job is done!' and returns an empty string before the user has a chance to type anything.

The reliable fix is to call keyboardInput.nextLine() immediately after any nextInt() or nextDouble() call — think of it as 'draining the leftover newline from the pipe.' Alternatively, you can read everything as strings using nextLine() and then parse the number yourself with Integer.parseInt() or Double.parseDouble(). The second approach also lets you show a friendly error message when the user types something unexpected instead of crashing.

SafeInputReading.java · JAVA
123456789101112131415161718192021222324252627282930313233343536373839
import java.util.Scanner;

public class SafeInputReading {
    public static void main(String[] args) {

        Scanner keyboardInput = new Scanner(System.in);

        // APPROACH 1 — Flush the buffer manually after nextInt()
        System.out.print("Enter your birth year: ");
        int birthYear = keyboardInput.nextInt();

        // This nextLine() drains the leftover '\n' from pressing Enter
        // Without this line, the next nextLine() would return "" (empty string)
        keyboardInput.nextLine(); // <--- the buffer flush

        System.out.print("Enter your home city: ");
        String homeCity = keyboardInput.nextLine(); // now works correctly

        System.out.printf("Born in %d, living in %s.%n", birthYear, homeCity);

        System.out.println();

        // APPROACH 2 — Read everything as String, then parse (safer & more flexible)
        System.out.print("Enter your salary: ");
        String salaryInput = keyboardInput.nextLine(); // read raw text

        double salary;
        try {
            // Parse the string into a number — throws NumberFormatException if invalid
            salary = Double.parseDouble(salaryInput);
            System.out.printf("Annual salary: $%.2f%n", salary);
        } catch (NumberFormatException conversionError) {
            // Friendly message instead of a crash
            System.out.println("That doesn't look like a valid number. Please enter digits only.");
        }

        keyboardInput.close();
    }
}
▶ Output
Enter your birth year: 1990
Enter your home city: London
Born in 1990, living in London.

Enter your salary: 75000.00
Annual salary: $75000.00
🔥
Interview Gold: Why Does nextLine() Return Empty After nextInt()?This exact question comes up in interviews. The answer: nextInt() consumes the numeric token but leaves the newline character in the stream. The immediately following nextLine() reads up to that newline, finds it instantly, and returns an empty string. Calling an extra nextLine() after nextInt() discards that leftover newline.

BufferedReader — The Faster, More Powerful Alternative

Scanner is perfect for learning and small programs, but professional Java developers often use BufferedReader for console input instead. The key difference is speed and control — BufferedReader reads large chunks of data at once (buffering them in memory), which is significantly faster when processing big files or high-throughput input.

BufferedReader requires a bit more setup. You wrap System.in in an InputStreamReader (which converts raw bytes to characters) and then wrap that in a BufferedReader (which adds efficient line-by-line reading). It sounds complex, but it's always the same three lines of setup code and you'll memorise them quickly.

The main trade-off: BufferedReader only reads strings — you always get back a String from readLine(), and you have to parse it yourself to get numbers. It also throws a checked IOException which means Java forces you to either handle it with try-catch or declare it with throws IOException. For beginners, Scanner is the right starting point. As you grow into professional Java, reach for BufferedReader.

In the code below, notice how both approaches produce the same result — the choice is about performance and context, not correctness.

BufferedReaderExample.java · JAVA
123456789101112131415161718192021222324252627282930313233343536
import java.io.BufferedReader;    // for fast, buffered reading
import java.io.InputStreamReader; // converts raw bytes (System.in) into characters
import java.io.IOException;       // must handle this checked exception

public class BufferedReaderExample {

    // 'throws IOException' tells Java: this method might throw an IO error
    // Java requires us to either handle it or declare it — we're declaring it here
    public static void main(String[] args) throws IOException {

        // Step 1: Wrap System.in in InputStreamReader to handle character encoding
        // Step 2: Wrap that in BufferedReader for efficient line reading
        BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("Enter the item name: ");
        String itemName = consoleReader.readLine(); // readLine() always returns a String

        System.out.print("Enter the quantity: ");
        // readLine() gives us "10" as a String — we parse it to int manually
        int quantity = Integer.parseInt(consoleReader.readLine());

        System.out.print("Enter the unit price: ");
        // Similarly, parse the string to a double
        double unitPrice = Double.parseDouble(consoleReader.readLine());

        double totalCost = quantity * unitPrice;

        System.out.println("\n--- Order Receipt ---");
        System.out.printf("Item     : %s%n", itemName);
        System.out.printf("Quantity : %d%n", quantity);
        System.out.printf("Unit Price: $%.2f%n", unitPrice);
        System.out.printf("Total    : $%.2f%n", totalCost);

        consoleReader.close(); // always close your reader
    }
}
▶ Output
Enter the item name: Mechanical Keyboard
Enter the quantity: 3
Enter the unit price: 89.99

--- Order Receipt ---
Item : Mechanical Keyboard
Quantity : 3
Unit Price: $89.99
Total : $269.97
⚠️
Pro Tip: Use try-with-resources to Auto-Close ReadersInstead of calling close() manually (and risking forgetting it), wrap your BufferedReader in a try-with-resources block: `try (BufferedReader reader = new BufferedReader(...)) { ... }`. Java will automatically close it when the block ends, even if an exception is thrown. This is the professional pattern.
FeatureScannerBufferedReader
Import neededjava.util.Scannerjava.io.BufferedReader + InputStreamReader
Reads numbers directly?Yes — nextInt(), nextDouble()No — must parse strings manually
Handles newline after nextInt?No — requires manual buffer flushNot an issue — always reads whole lines
PerformanceSlower (tokenises input)Faster (buffers large chunks)
Exception handling required?No checked exceptionsYes — must handle IOException
Best forBeginner projects, simple console appsProfessional apps, file reading, performance-critical code
Setup complexitySimple — one lineModerate — three wrapped classes

🎯 Key Takeaways

  • System.out.println() adds a newline after printing; System.out.print() doesn't — mix them intentionally to control exactly where your cursor lands.
  • Scanner requires import java.util.Scanner and must be wrapped around System.in — create one instance and reuse it, never create a new Scanner per read operation.
  • The nextInt() + nextLine() buffer bug is one of the most common beginner traps in Java — always flush the buffer with an extra nextLine() after reading a number if you plan to read a string next.
  • BufferedReader is faster and more professional than Scanner but requires more setup and manual number parsing — start with Scanner, graduate to BufferedReader as your programs grow.

⚠ Common Mistakes to Avoid

  • Mistake 1: Calling nextLine() immediately after nextInt() without a buffer flush — The nextLine() returns an empty string silently, causing downstream logic to fail with blank data or wrong output — Fix: add a throwaway keyboardInput.nextLine() call right after nextInt() or nextDouble() to consume the leftover newline character before reading your actual string.
  • Mistake 2: Forgetting to import Scanner — The compiler throws 'cannot find symbol: class Scanner' even though the code looks correct — Fix: add import java.util.Scanner; as the very first line after your package declaration. This import is mandatory; Scanner is not automatically available like System is.
  • Mistake 3: Using nextLine() to read a number and skipping the parseInt/parseDouble conversion — The program compiles and runs but stores '42' as a String, causing a 'incompatible types' error the moment you try to do arithmetic — Fix: always convert with Integer.parseInt(stringValue) or Double.parseDouble(stringValue) and wrap it in a try-catch to handle invalid input gracefully.

Interview Questions on This Topic

  • QWhat is the difference between System.out.print(), System.out.println(), and System.out.printf() in Java? When would you choose each one?
  • QWhy does calling nextLine() immediately after nextInt() on the same Scanner object often return an empty string, and what are two ways to fix it?
  • QWhat are the advantages of using BufferedReader over Scanner for reading console input in a production Java application?

Frequently Asked Questions

How do I read user input in Java?

The easiest way is to use Java's Scanner class. Import it with import java.util.Scanner;, create an instance with Scanner input = new Scanner(System.in);, then call methods like input.nextLine() for text or input.nextInt() for whole numbers. Always close the Scanner with input.close() when you're done.

What is the difference between print and println in Java?

Both print to the console, but System.out.println() automatically adds a newline character at the end, moving the cursor to the next line. System.out.print() prints the value and leaves the cursor right where it stopped — the next print will appear on the same line. Use println for most output; use print when you want to build output on one line piece by piece.

Do I always need to import Scanner in Java?

Yes, always. Scanner lives in the java.util package which is not automatically imported. You must add import java.util.Scanner; at the top of your file before your class declaration. The only classes Java imports automatically are those in java.lang, such as String, Math, and System.

🔥
TheCodeForge Editorial Team Verified Author

Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.

← PreviousType Casting in JavaNext →Comments in Java
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged