28

I'm working on a game and I came across a little problem with my scanner. I'm getting a resource leak scanner never closed.

But I thought my scanner was working before without closing it. But now it ain't. Anyone can help me out here?

import java.util.Scanner;

public class Main {

    public static final boolean CHEAT = true;

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        int amountOfPlayers;
        do {
            System.out.print("Select the amount of players (1/2): ");
            while (!scanner.hasNextInt()) {
                System.out.println("That's not a number!");
                scanner.next(); // this is important!
        }

        amountOfPlayers = scanner.nextInt();
        while ((amountOfPlayers <= 0) || (amountOfPlayers > 2));
        System.out.println("You've selected " + amountOfPlayers+" player(s)."); 
    }
}
gunr2171
  • 10,315
  • 25
  • 52
  • 75

4 Answers4

52

I am assuming you are using java 7, thus you get a compiler warning, when you don't close the resource you should close your scanner usually in a finally block.

Scanner scanner = null;
try {
    scanner = new Scanner(System.in);
    //rest of the code
}
finally {
    if(scanner!=null)
        scanner.close();
}

Or even better: use the new Try with resource statement:

try(Scanner scanner = new Scanner(System.in)){
    //rest of your code
}
ʇolɐǝz ǝɥʇ qoq
  • 770
  • 1
  • 13
  • 28
PermGenError
  • 43,905
  • 8
  • 81
  • 104
  • Should `new Scanner(System.in)` be surrounded with `try-catch` block? – Maroun Mar 25 '13 at 11:23
  • @MarounMaroun not necessarily. but its a good practice to close your resouces inside a finally block. – PermGenError Mar 25 '13 at 11:24
  • 1
    Thanks, realy like the Try with resource statement, works like a charm! – Niek van der Linden Mar 25 '13 at 11:28
  • @NiekvanderLinden btw, just want to mention this. its just a compiler warning you are getting and i am most certainly sure this wouldn't case any problems with how your scanner functions. compiler is just telling you that you have to close your resource which you have opened in order to prevent leak . :) – PermGenError Mar 25 '13 at 11:30
  • 1
    @PermGenError Thanks for the heads up, the scanner was working fine but i didn't like the error :) – Niek van der Linden Mar 25 '13 at 11:35
  • 11
    Why are you closing `System.in` by yourself? It is the job of the jvm at shutdown. – Eng.Fouad Mar 25 '13 at 11:36
  • @PermGenError - Why do we need to close Scanner ? What is meant by "resource leak" ? – Erran Morad May 04 '14 at 22:18
  • 3
    @Eng.Fouad - Then why does eclipse keep throwing the warning ? It makes me wonder if I am doing something wrong. – Erran Morad May 04 '14 at 22:19
  • 1
    As @Eng.Fouad noted before. I don't recommend closing System.in, as you might need it elsewhere. I am annoyed by warnings for not closing resources that operate on System.in, as in practice you'd really never want to close System.in. Always resorted to using a warning suppression or a CloseShieldInputStream (http://commons.apache.org/io/apidocs/org/apache/commons/io/input/CloseShieldInputStream.html) – AgentM Jun 17 '20 at 15:29
6

According to the Javadoc of Scanner, it closes the stream when you call it's close method. Generally speaking, the code that creates a resource is also responsible for closing it. System.in was not instantiated by by your code, but by the VM. So in this case it's safe to not close the Scanner, ignore the warning and add a comment why you ignore it. The VM will take care of closing it if needed.

(Offtopic: instead of "amount", the word "number" would be more appropriate to use for a number of players. English is not my native language (I'm Dutch) and I used to make exactly the same mistake.)

Henno Vermeulen
  • 1,427
  • 2
  • 15
  • 25
1

Here is some better usage of java for scanner

try(Scanner sc = new Scanner(System.in)) {

    //Use sc as you need

} catch (Exception e) {

        //  handle exception

}
Priyantha
  • 3,687
  • 4
  • 21
  • 40
0

Try this

Scanner scanner = new Scanner(System.in);
int amountOfPlayers;
do {
    System.out.print("Select the amount of players (1/2): ");
    while (!scanner.hasNextInt()) {
        System.out.println("That's not a number!");
        scanner.next(); // this is important!
    }

    amountOfPlayers = scanner.nextInt();
} while ((amountOfPlayers <= 0) || (amountOfPlayers > 2));
if(scanner != null) {
    scanner.close();
}
System.out.println("You've selected " + amountOfPlayers+" player(s).");
tmwanik
  • 1,565
  • 13
  • 19