Beginner's Guide To Java Scanner (With Code Examples)

Maaike van Putten
Maaike van Putten
hero image

Have you ever tried making a Java program that asks the user for input, only for it to crash, skip entries, or behave unpredictably? If so, you’re not alone.

Handling user input in Java seems simple but often leads to frustrating bugs if you don’t know the right approach. Maybe your program asks for a number but crashes when someone enters text, or it skips a question entirely.

That’s where Scanner comes in. It’s Java’s easiest way to read user input

In this guide, I’ll break it all down and show you how to avoid common pitfalls so that by the time you finish reading, you’ll be able to use this tool with your own projects.

Let’s dive in…

Sidenote: If you find that you’re struggling with the topics in this guide, or perhaps feel that you could use some more training, or simply want to build some more impressive projects for your portfolio, then check out my Java programming bootcamp:

You'll learn Java programming fundamentals all the way from complete beginner to advanced skills.

Better still, you’ll be able to reinforce your learning with over 80 exercises and 18 quizzes. This is the only course you need to go from complete programming beginner to being able to get hired as a Backend Developer!

With that out of the way, let’s get into the tutorial…

What is the Java Scanner class?

When writing Java programs, you sometimes need a way to accept user input. Maybe you’re building a calculator that requires numbers, a quiz that takes answers, or a login system that asks for a username and password.

Without input handling, Java programs are limited to hardcoded values.

For example

Imagine writing a program that asks for a user's name. Without input handling, you'd have to hardcode the name inside the program like so:

public class Main {
	public static void main(String[] args) {
    	String name = "Alice"; // Hardcoded name
    	System.out.println("Hello, " + name + "!");
	}
}
Sure it works, but every time you run this program, it will always print ``"Hello, Alice!"``. Obviously this is not great if you wanted to greet someone else, as you’d have to manually change ``"Alice"`` in the code and recompile the program, which is not at all practical.

Scanner solves this by allowing users to interact with the program at runtime and use their response dynamically instead.

For example

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
    	Scanner scanner = new Scanner(System.in);
    	System.out.print("Enter your name: ");
    	String name = scanner.nextLine();
    	System.out.println("Hello, " + name + "!");
	}
}

When this program runs, it will pause and wait for the user to type their name. Once they press Enter, the program will greet them personally with no hardcoded values needed.

Let’s take a look at this code so we can understand how it works, step by step:

  1. Scanner scanner = new Scanner(System.in); → Creates a Scanner object linked to the keyboard (System.in)

  2. System.out.print("Enter your name: "); → Displays a message asking the user for input

  3. String name = scanner.nextLine(); → Reads an entire line of text from the user

  4. System.out.println("Hello, " + name + "!"); → Prints a personalized greeting using the user’s input

Super handy right?

So let’s show you how to set it up.

How to set up and import Scanner

Since Scanner isn’t automatically available in Java, the first thing you need to do is import it.

Importing Scanner

Java organizes its built-in tools into packages, and Scanner belongs to the java.util package. To use it, you need to import it at the beginning of your program:

import java.util.Scanner;

This tells Java, "I want to use the Scanner class in this program."

Without this import, trying to use Scanner would result in a compilation error.

How to create a Scanner object (and why you need it)

Once you've imported Scanner, you need to create a Scanner object to actually start reading input. The most common way to do this is by linking it to System.in, which represents input from the keyboard:

Scanner scanner = new Scanner(System.in);

This line creates a new Scanner object and connects it to the keyboard, allowing your program to accept user input.

How to use Scanner

Now that Scanner is set up, let’s explore how to read different types of input correctly without running into skipped inputs or crashes.

At a high level:

  • If you need a single word, next() works fine

  • If you need a full sentence, nextLine() is the better choice

  • If you’re dealing with numbers, use nextInt() or nextDouble()

  • If you’re expecting true/false values, nextBoolean() is what you need

The trick is knowing when to use each method, because picking the wrong one can lead to skipped inputs, unexpected results, or program crashes.

Let’s go through them one by one.

How to read text input with next() and nextLine()

User input often includes single-word responses, full names, or entire sentences. Java provides two different methods for handling this:

  • next(): Reads a single word and stops at the first space

  • nextLine(): Reads everything the user types until they press Enter

These two methods behave very differently, so choosing the wrong one can break your program in ways that are frustrating to debug.

For example

Let’s say you ask the user for their name and print a greeting:

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.next();
System.out.println("Hello, " + name + "!");
You run the program, they enter ``"John"``, and everything works as expected. But then they try to enter their full name ``"John Doe"``, and suddenly, only ``"John"`` is printed.

So where did "Doe" go?

The issue is that next() only reads a single word and stops at the first space. This means that anything after that stays in the input buffer, waiting to be read. (If you expected "John Doe", but only "John" appears, it’s because "Doe" is still sitting there, unread).

So if you actually want the full name, nextLine() is the better option:

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Hello, " + name + "!");

Now, "John Doe" is captured correctly as a single input. Huzzah!

Should you always use nextLine() instead of next()?

No, simply because next() is still useful in certain situations:

  1. When you only need a single word, like a first name or a command

  2. Or when reading multiple values from a single line

For example

If we look at the example below, we want to read multiple values from a single line. In this case, "Alice 25" (name and age).

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your first name and age: ");
String firstName = scanner.next();  
int age = scanner.nextInt();  
System.out.println(firstName + " is " + age + " years old.");

This code works because next() reads "Alice", and nextInt() reads 25, all in one go. But if we had used nextLine() instead, we would have to manually split the input later.

How to read numbers with nextInt() and nextDouble()

When reading numbers, Scanner provides methods to handle both integers and floating-point values.

Using nextInt() for whole numbers

If you need to read a whole number, nextInt() is the right choice, because it ensures that only valid integers are accepted.

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: ");
int age = scanner.nextInt();
System.out.println("You are " + age + " years old.");

However, if the user enters letters instead of a number, the program will crash with an InputMismatchException. (We’ll cover how to prevent this later).

Using nextDouble() for decimals

So, if you expect decimal values, like prices or weights, then nextDouble() is a better choice.

Scanner scanner = new Scanner(System.in);
System.out.print("Enter the price: ");
double price = scanner.nextDouble();
System.out.println("The price is $" + price);

This ensures that the user's input is recognized as a floating-point number rather than an integer.

How to read Boolean input

For true/false values, nextBoolean() reads "true" or "false" and automatically converts it into a boolean.

For example

Scanner scanner = new Scanner(System.in);
System.out.print("Are you over 18? (true/false): ");
boolean isAdult = scanner.nextBoolean();
System.out.println("You answered: " + isAdult);

If the user types anything other than "true" or "false", Java will throw an error. That’s why, if you’re expecting answers like "yes" or "no", it’s better to read the input as a String using nextLine() and check the value manually.

Simple!

Best practices for using Scanner

Using Scanner correctly isn’t just about avoiding errors. It’s also about writing clean, maintainable, and efficient code.

With that in mind, here are some best practices to follow that will help you structure your input handling properly and avoid unnecessary issues down the line.

#1. Use a single Scanner instance for user input

A common mistake is creating multiple Scanner instances for keyboard input. While it might seem harmless, doing this can cause unexpected behavior and even lead to input stream conflicts.

Bad practice

Scanner scanner1 = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner1.nextLine();
Scanner scanner2 = new Scanner(System.in);
System.out.print("Enter your age: ");
int age = scanner2.nextInt(); // Potential issues

Sure, using a single Scanner prevents input conflicts and keeps your code cleaner. But as your program grows, having all input logic in one place can make it harder to maintain.

That’s why it’s also important to structure your code properly by keeping input handling modular.

Best practice

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.print("Enter your age: ");
int age = scanner.nextInt(); 

This makes your code cleaner and prevents input stream conflicts.

#2. Keep Scanner code modular and reusable

If your program needs to take multiple inputs, avoid putting all Scanner logic in main(). Instead, break it into separate functions so your code is easier to read and reuse.

Bad practice

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.print("Enter your age: ");
int age = scanner.nextInt();
System.out.println("Hello, " + name + ". You are " + age + " years old.");

This bad practice solution works but as the program grows, it becomes harder to maintain. A better approach is to separate concerns into functions, like so:

Best practice

import java.util.Scanner;
public class UserInput {

	private static Scanner scanner = new Scanner(System.in);
	public static String getName() {
    	System.out.print("Enter your name: ");
    	return scanner.nextLine();
	}

	public static int getAge() {
    	System.out.print("Enter your age: ");
    	return scanner.nextInt();
	}

	public static void main(String[] args) {
    	String name = getName();
    	int age = getAge();
    	System.out.println("Hello, " + name + ". You are " + age + " years old.");
	}
}

Structuring your code this way makes it easier to manage and scale.

But even with well-structured code, you still need to ensure users provide valid input, otherwise, your program might still crash. That’s where input validation comes in.

#3. Use input validation to handle unexpected input

If you expect the user to enter numbers, it's a good idea to always assume they might enter something invalid (like letters). So instead of letting the program crash, validate input before using it.

Bad practice

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: ");
int age = scanner.nextInt(); // CRASHES if the user enters text

Best practice

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: ");
while (!scanner.hasNextInt()) {
	System.out.println("Invalid input. Please enter a number.");
	scanner.next(); // Discard invalid input
}
int age = scanner.nextInt();
System.out.println("You are " + age + " years old.");

Even with validation in place, handling input properly also means knowing when to close Scanner. Closing it at the wrong time can break your program so let’s go over when to close it and when to keep it open.

#4. Be mindful when closing Scanner

When reading from a file, you should always close Scanner after you're done. However, it's important to remember that if you're reading from System.in (keyboard input), closing Scanner will close the input stream for the entire program.

So as a rule of thumb:

  • Reading from a file? Always close it

  • Reading from System.in? Don't close it if you need more input later

Bad practice

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
scanner.close(); // Closes System.in
System.out.print("Enter your age: ");
int age = scanner.nextInt(); // ERROR: Scanner is closed!

Best practice

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
// Keep scanner open if you need more input
System.out.print("Enter your age: ");
int age = scanner.nextInt();

#5. Handling Passwords? Console is a more secure option

If your program asks users to enter passwords or other sensitive information, Scanner is a bad choice because it displays everything the user types, which is not ideal for security.

That’s where Console comes in.

For example

Here’s how Console might work in a login system:

import java.io.Console;

public class Main {
	public static void main(String[] args) {
    	Console console = System.console();
    	if (console != null) {
        	char[] password = console.readPassword("Enter password: ");
        	System.out.println("Password received.");
    	} else {
        	System.out.println("Console not supported in this environment.");
    	}
	}
}

This method keeps input hidden while typing, making it more secure than Scanner. However, System.console() only works when running Java from a terminal, and some IDEs such as Eclipse, may not support it.

Common mistakes and how to fix them

Now that you know the best practices, let's cover all our bases and make sure you’re aware of any common issues that you might come across, their causes, and how to resolve them.

#1. Forgetting to import Scanner!

Such a rookie move but we all fall for it at some point. If you remember from earlier, Scanner is part of the java.util package, which means it isn’t automatically available.

So if you forget to import it, your program won’t compile, and you’ll see this error:

Main.java:3: error: cannot find symbol
	Scanner scanner = new Scanner(System.in);
	^
  symbol:   class Scanner
  location: class Main

Super simple to fix. Just always remember to include this line at the top of your Java file:

import java.util.Scanner;

This tells Java where to find the Scanner class so your program can use it.

#2. Not initializing Scanner before using it

Declaring a Scanner variable without initializing it will cause a compilation error when you try to use it.

This is because Java requires local variables to be assigned a value before they're accessed.

For example

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner scanner; // Declared but not initialized

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

        String name = scanner.nextLine(); // Compilation error!

        System.out.println("Hello, " + name + "!");

    }

}

If you explicitly set the variable to null instead, the code will compile, but calling a method such as nextLine() will throw a NullPointerException.

How to fix it

Make sure you initialize Scanner before using it with Scanner scanner = new Scanner(System.in);

#3. Skipping input after nextInt() or nextDouble()

One of the most frustrating issues is when Scanner skips input after reading a number.

For example

If you mix nextInt() or nextDouble() with nextLine(), the program may skip the next text input.

Scanner scanner = new Scanner(System.in);

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

int age = scanner.nextInt(); // Reads the number

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

String name = scanner.nextLine(); // Skips input!

System.out.println("Hello, " + name + "!");

Why does this happen?

This is because nextInt() reads the number but leaves the newline (\n) in the input. So when nextLine() is called next, it immediately consumes that leftover newline instead of waiting for the user to enter their name.

When you're reading one input per line, you can fix this by consuming the remaining newline before calling nextLine():

Scanner scanner = new Scanner(System.in);

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

int age = scanner.nextInt();

scanner.nextLine(); // Consume leftover newline

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

String name = scanner.nextLine();

System.out.println("Hello, " + name + "!");

Now, nextLine() will correctly wait for the user's name.

#4. InputMismatchException when entering the wrong data type

If the user enters text when nextInt() or nextDouble() expects a number, Java throws an InputMismatchException, causing the program to crash.

For example

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: ");
int age = scanner.nextInt();  // CRASHES if input is not a number!

If the user types "twenty" instead of 20, the program crashes with this error:

Exception in thread "main" java.util.InputMismatchException
	at java.util.Scanner.nextInt(Unknown Source)

The solution for this is to always check if the input is valid before reading it:

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: ");
while (!scanner.hasNextInt()) {
	System.out.println("Invalid input. Please enter a number.");
	scanner.next();  // Discard invalid input
}
int age = scanner.nextInt();
System.out.println("You are " + age + " years old.");

#5. Decimal input fails in some countries due to locale issues

In some regions, decimal numbers are written with a comma (1,99) instead of a dot (1.99). This can cause problems because Scanner uses locale-specific rules when reading numbers.

For example

If your program expects a dot as the decimal separator but the user enters a comma, nextDouble() may throw an InputMismatchException.

Scanner scanner = new Scanner(System.in);

System.out.print("Enter a price: ");

double price = scanner.nextDouble(); // May fail if input is "1,99"

System.out.println("The price is $" + price);

How to fix it

If your application expects users to enter numbers using US formatting conventions, you can explicitly set the locale:

import java.util.Locale;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in).useLocale(Locale.US);

        System.out.print("Enter a price: ");

        double price = scanner.nextDouble();

        System.out.println("The price is $" + price);

    }

}

Now, Java will interpret decimal numbers using US formatting conventions, so users should enter 1.99 rather than 1,99.

However, this doesn't mean the program automatically supports every regional number format. If you're building an application for international users, you'll need to account for the number formats your users actually enter.

Easy!

Time to give a Scanner a try with your own code!

So as you can see, Scanner makes it easy to handle user input in Java, but only if you use it correctly. But by following best practices and avoiding common mistakes, you’ll write input-handling code that works smoothly every time.

The best way to reinforce what you’ve learned? Try it yourself!

Go ahead and write some small programs that take different types of input: words, sentences, numbers, etc, and experiment with validation to prevent errors.

The more you practice, the more intuitive Scanner will become. So put your knowledge to the test and start coding 😁.

P.S.

Remember, if you want to fast-track your Java knowledge and get as much hands-on practice as possible, then check out my Java programming bootcamp:

You'll learn Java programming fundamentals all the way from complete beginner to advanced skills.

Better still, you’ll be able to reinforce your learning with over 80 exercises and 18 quizzes. This is the only course you need to go from complete programming beginner to being able to get hired as a Backend Developer!

Plus, once you join, you'll have the opportunity to ask questions in our private Discord community from me, other students and working DevOps professionals.

Best articles. Best resources. Only for ZTM subscribers.

If you enjoyed this post and want to get more like it in the future, subscribe below. By joining the ZTM community of over 100,000 developers you’ll receive Web Developer Monthly (the fastest growing monthly newsletter for developers) and other exclusive ZTM posts, opportunities and offers.

No spam ever, unsubscribe anytime

More from Zero To Mastery

Java Coding Interview Questions + Answers (With Code Examples) preview
Java Coding Interview Questions + Answers (With Code Examples)
47 min read

Your go-to guide for Java interviews! Discover the top questions and answers to prepare for success and stand out in your next interview.

Beginner's Guide To compareto In Java (With Code Examples) preview
Beginner's Guide To compareto In Java (With Code Examples)
17 min read

Master Java’s compareTo method in minutes! Learn how to compare objects, avoid common mistakes, and write cleaner code with hands-on examples.

Beginner's Guide To Try And Catch In Java preview
Beginner's Guide To Try And Catch In Java
20 min read

Java errors crash your code, but they don’t have to. Learn how try and catch keep your program running smoothly — stop errors before they stop you!