Close your Scanner by calling the close() method when you're done reading input

A Scanner in Java is an object that reads input from a source — a file, the keyboard, a network stream, or any other input source. When you create a Scanner, Java sets aside system resources to handle that input. If you don't close the Scanner when you're finished, those resources stay open and can't be used by other parts of your program or other programs on your machine.

The fix is straightforward: call scanner.close() when you're done reading. This tells Java to release those resources when ready. Without this step, your program may leak resources — meaning it holds onto them even after it no longer needs them.

Key Takeaways

  • Call close() on your Scanner object as soon as you finish reading input to release system resources.
  • The safest way is to use a try-with-resources statement, which closes the Scanner automatically even if an error occurs.
  • If you use Scanner in a traditional try-catch block, put close() in a finally block so it runs whether or not an exception happens.
  • Forgetting to close a Scanner won't crash your program when ready, but it wastes memory and can cause problems if you create many Scanners in a loop.

Using try-with-resources: the modern approach

Java 7 introduced a feature called try-with-resources that closes a Scanner automatically. You declare the Scanner inside the parentheses of a try statement, and Java closes it for you when the try block ends — even if an exception is thrown.

Here's the pattern:

try (Scanner scanner = new Scanner(System.in)) {   String line = scanner.nextLine();   System.out.println(line); } // Scanner is closed here automatically

This is the recommended way because it's short, clear, and handles errors correctly. You don't have to remember to write a finally block or worry about whether close() will run if something goes wrong.

Using a finally block if you can't use try-with-resources

If you're working with older Java code or a situation where try-with-resources doesn't fit, put your close() call in a finally block. A finally block runs no matter what — whether the try block succeeds, throws an exception, or returns early.

Scanner scanner = new Scanner(System.in); try {   String line = scanner.nextLine();   System.out.println(line); } finally {   scanner.close(); } // Scanner is closed here

This pattern ensures close() runs in all cases. The downside is that it's more verbose than try-with-resources, and you have to remember to include the finally block every time you use a Scanner.

What happens if you don't close a Scanner

Your program won't crash when ready if you forget to close a Scanner. The resource leak happens silently — Java holds onto the underlying input stream, file handle, or network connection even though your code is no longer using it.

If your program creates only one or two Scanners and then exits, the operating system cleans up the resources when the program stops. But if you create many Scanners in a loop without closing them, you can run out of file handles or memory. This is especially common in server applications that handle many requests, where each request might create a Scanner and forget to close it.

The best practice is to close every Scanner you create, even if you think the resource leak won't matter in your specific case. It's a habit that prevents bugs later.

Closing a Scanner that reads from a file

When your Scanner reads from a file instead of the keyboard, closing becomes even more important. An open file handle can prevent other programs from reading or modifying that file.

try (Scanner scanner = new Scanner(new File("data.txt"))) {   while (scanner.hasNextLine()) {     String line = scanner.nextLine();     System.out.println(line);   } } // File is closed here

Using try-with-resources here is especially valuable because it closes the file even if an exception occurs while reading. If you use a finally block instead, make sure to catch any IOException that close() might throw.

Closing a Scanner in a loop

If you create multiple Scanners in a loop, close each one before the next iteration. This is where resource leaks become visible — if you create 1,000 Scanners without closing them, you'll run out of file handles quickly.

for (int i = 0; i < 10; i++) {   try (Scanner scanner = new Scanner(new File("file" + i + ".txt"))) {     String line = scanner.nextLine();     System.out.println(line);   } } // Each Scanner is closed at the end of each iteration

The try-with-resources statement closes the Scanner at the end of each iteration, so the next iteration can safely create a new one.

Frequently Asked Questions

What if I close the Scanner and then try to read from it again?

You'll get an exception: IllegalStateException: Scanner closed. Once a Scanner is closed, you can't use it anymore. If you need to read more input, you have to create a new Scanner.

Does closing a Scanner close the underlying input stream?

Yes. When you close a Scanner, it also closes the stream it's reading from — whether that's a file, System.in, or a network socket. If you need to keep reading from that stream with something else, don't close the Scanner.

Can I close a Scanner multiple times?

Yes, calling close() multiple times is safe. The first call closes the Scanner; subsequent calls do nothing. This is why try-with-resources is safe even if you also call close() manually.

What's the difference between close() and closing the stream manually?

Calling scanner.close() closes the Scanner and its underlying stream in one step. You don't need to close the stream separately. If you created the stream yourself (like new FileInputStream("file.txt")), you'd normally close that stream, but when you pass it to a Scanner, let the Scanner handle closing it.