При закрытии объекта Scanner он также закрывает связанный с ним объект InputStream или файл. Если бы вы использовали Scanner
в вашем input()
методе для чтения данных из файла, а не с клавиатуры, вы можете использовать его следующим образом:
String input() {
InputStream is = new FileInputStream(INPUT_FILE_NAME);
Scanner s = new Scanner(is);
String str = s.nextLine();
s.close();
return str;
}
Как видите, сканер закрыт, поэтому нет утечек ресурсов. Если вы не закроете его, InputStream, который был открыт для файла, останется открытым. Простое закрытие сканера также закрывает InputStream, на котором был построен сканер. Поэтому нет необходимости также закрывать InputStream.
Вышеуказанное эквивалентно следующему, но приведенный ниже код безопаснее, поскольку он правильно обрабатывает исключения:
String input() {
try (
InputStream is = new FileInputStream(INPUT_FILE_NAME);
Scanner s = new Scanner(is)
) {
String str = s.nextLine();
return str;
}
}
Это заявление о попытках использования ресурсов, о котором вы можете прочитать на веб-сайте Oracle или в хорошем учебнике. Это гарантирует, что InputStream и Scanner всегда закрываются до возврата метода, независимо от того, что происходит.
Так почему бы нам не сделать то же самое со сканером, который открыт в System.in
? Это потому, что System.in
является InputStream, который мы хотим держать открытым в течение всей продолжительности программы. Если мы закроем сканер, это также закроет System.in
, и мы этого не хотим. Но теперь, когда мы не закрываем Сканер, мы не хотим создавать новый Сканер каждый раз, когда вводим метод input()
. Мы просто хотим создать один сканер, который будет работать в течение всей нашей программы. Один из способов сделать это - указать его в виде поля:
public class Validation {
private static Scanner in = new Scanner(System.in);
String input() {
return in.nextLine();
}
...
}
Теперь сканер создается, как только JVM загружает ваш класс, и остается доступным для использования до выхода из вашей программы.
Я не уверен, будет ли Eclipse по-прежнему жаловаться на утечку ресурсов, если вы создадите объект Scanner как статическое поле (я не использую Eclipse). Возможно, вы можете дать мне знать, если это так.