Quantcast
Channel: Baeldung
Viewing all articles
Browse latest Browse all 3780

Closing Scanner in Java

$
0
0
almost done featured

1. Introduction

When we use Java’s Scanner class to read input from System.in, some IDEs may warn about a potential resource leak. For instance, if we don’t explicitly close the Scanner we may face a warning like “Resource leak: ‘scanner’ is never closed. However, closing a Scanner connected to System.in requires careful handling to avoid unexpected issues.

In this tutorial, we’ll learn why closing a Scanner is important and how to do it in Java.

2. Understanding the Warning

In Java, we should close resources like files, network connections, and input streams after use to free up system memory. The Scanner class reads input, such as primitive values and strings, from various sources, including files and System.in. Since it implements the Closeable interface, it holds resources that should be released when no longer needed.

Some IDEs, like Eclipse and Visual Studio Code, display warnings if we don’t properly close a Scanner object. For example, if we don’t explicitly close a Scanner object, the IDE displays the resource leak warning:

warning resource leak

3. Closing a Scanner With the close() Method

In Java, we can close a Scanner using the close() method, which helps free system resources. It’s especially important when reading from a file or System.in.

It’s recommended to close a Scanner in the finally block to ensure proper closure even if an exception occurs. This helps prevent resource leaks:

@Test
void givenUserName_whenGetGreetingMessage_thenReturnsWelcomeMessage() {
    String input = "Anees\n";
    ByteArrayInputStream inputStream = new ByteArrayInputStream(input.getBytes());
    Scanner scanner = new Scanner(inputStream);
    ScannerClose example = new ScannerClose();
    String result = example.getGreetingMessage(scanner);
    assertEquals("Hi, Anees Welcome to Baeldung", result);
    scanner.close();
}

Closing resources is a good practice. However, closing a Scanner linked to System.in can cause problems. The System.in stream represents the standard input stream, generally the keyboard. If we close this stream, the program can no longer read user input, and we can’t reopen System.in within the same program execution.

Moreover, if we create multiple Scanner instances for System.in, closing any of them will shut down the input stream for the entire program. As a result, we may encounter exceptions when trying to read input again:

Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Hi, " + name + " Welcome to Baeldung!");
scanner.close();
System.out.print("Enter your age: ");
int age = scanner.nextInt();
System.out.println("Your age is: " + age);

Here, we try to read age, but the Scanner was closed earlier. As a result, we encounter an exception IllegalStateException: Scanner closed:

Enter your name: Anees
Hi, Anees Welcome to Baeldung!
Enter your age: Exception in thread "main" java.lang.IllegalStateException: Scanner closed
    at java.base/java.util.Scanner.ensureOpen(Scanner.java:1150)
    at java.base/java.util.Scanner.next(Scanner.java:1573)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2212)

To avoid issues with Scanner, we should use a single instance for System.in and either avoid closing it or close it only when we no longer need input.

4. Closing a Scanner Using try-with-resources

We can use try-with-resources to close the Scanner automatically at the end of the block, even if an exception occurs. This approach eliminates the need for a finally block and automatically closes resources, which reduces the risk of resource leaks:

@Test
void givenUserName_whenGetGreetingMessage_thenReturnsWelcomeMessage() {
    String input = "Anees\n";
    ByteArrayInputStream inputStream = new ByteArrayInputStream(input.getBytes());
    String result;
    try (Scanner scanner = new Scanner(inputStream)) {
        ScannerTryWithResources example = new ScannerTryWithResources();
        result = example.getGreetingMessage(scanner);
    }
    assertEquals("Hi, Anees Welcome to Baeldung", result);
}

When the try block finishes execution, Java automatically closes the Scanner instance, making the code cleaner and more reliable. Therefore, try-with-resources is recommended as it ensures proper cleanup when closing a Scanner.

5. Conclusion

In this article, we learned why closing a Scanner is important and how to do it correctly. Proper resource management helps prevent leaks and ensures smooth program execution.

While closing a Scanner is necessary when reading from files, handling System.in requires extra caution. Using a single Scanner instance and closing it only when we no longer need input helps avoid issues.

The try-with-resources approach simplifies resource management by ensuring automatic closure, making the code cleaner and more reliable.

As usual, the complete example code is available over on GitHub.

The post Closing Scanner in Java first appeared on Baeldung.
       

Viewing all articles
Browse latest Browse all 3780

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>