Java Input and Output Explained — Scanner, System.out and Real Examples
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.
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); } }
First name: Ada Lovelace
Product : Java Book
In Stock : 42 units
Price : $29.99
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.
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(); } }
Enter your age: 35
Enter your account balance: 4820.50
--- Profile Summary ---
Name : Marie Curie
Age : 35 years old
Balance : $4820.50
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.
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(); } }
Enter your home city: London
Born in 1990, living in London.
Enter your salary: 75000.00
Annual salary: $75000.00
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.
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 } }
Enter the quantity: 3
Enter the unit price: 89.99
--- Order Receipt ---
Item : Mechanical Keyboard
Quantity : 3
Unit Price: $89.99
Total : $269.97
| Feature | Scanner | BufferedReader |
|---|---|---|
| Import needed | java.util.Scanner | java.io.BufferedReader + InputStreamReader |
| Reads numbers directly? | Yes — nextInt(), nextDouble() | No — must parse strings manually |
| Handles newline after nextInt? | No — requires manual buffer flush | Not an issue — always reads whole lines |
| Performance | Slower (tokenises input) | Faster (buffers large chunks) |
| Exception handling required? | No checked exceptions | Yes — must handle IOException |
| Best for | Beginner projects, simple console apps | Professional apps, file reading, performance-critical code |
| Setup complexity | Simple — one line | Moderate — 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.Scannerand 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.
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.