2014-11-15 4 views
0

У меня есть этот код, который вызывает метод, чтобы проверить, является ли число определенной длиной, а если нет, новый номер должен быть повторно введен пользователем.Как правильно закрыть класс сканера внутри метода?

Проблема заключается в том, что я не могу найти подходящий способ закрыть класс сканера, чтобы предотвратить утечку ресурсов.

Код указан в данный момент.

public static void setIdentification(Person p, int dni) { 
    Scanner input = new Scanner (System.in); 
    String lengthChecker = Integer.toString(dni); 
    if (lengthChecker.length() < 1 || lengthChecker.length() > 8) { 
     int dni1; 
     do{ 
      System.out.println("The ID number isn't valid. Please, introduce a valid number: "); 
      dni1 = input.nextInt(); 
      lengthChecker = Integer.toString(dni1); 
      } while (lengthChecker.length() > 8 || lengthChecker.length() < 1); 
     p.dni = dni1; 
    } else { 
     p.dni = dni; 
    } 
} 
public static void main(String[] args) { 
    Scanner input1 = new Scanner (System.in); 
    int dni = input1.nextInt(); 
    Person person1 = new Person(); 
    setIdentification(person1, dni); 
} 

Я попытался установить input.close(); в ряде различных мест, но я всегда в конечном итоге получаю ошибку во время выполнения.

Существует, вероятно, миллион способов оптимизации этого кода, но прямо сейчас мне просто интересно узнать, как закрыть эти сканеры.

+0

Сканеры реализуют 'AutoCloseable', поэтому вы можете обернуть их в блок try-with-resources. – toniedzwiedz

ответ

3

@Jules правильный. В этом случае не нужно или желательно закрыть Scanner.

Но если предположить, что вы сделали, то рекомендуемый способ сделать это заключается в следующем:

try (Scanner input1 = new Scanner (System.in)) { 
    int dni = input1.nextInt(); 
    Person person1 = new Person(); 
    setIdentification(input1, person1, dni); 
} 

... отметить, что вы должны изменить метод setIdentification так, что он не пытается открыть свой собственный сканер , Ошибка при создании нескольких сканеров для одного входного потока. Действительно, это ошибка в вашем коде.

Это работает для Java 7 и более поздних версий. (В большинстве случаев, вы не должны писать новый код для более старых версий Java. Android является исключением, потому что поддержка Java 7 расширений только недавно стала доступна в Android компилированных инструментах.


Так почему не могут вы открывать и закрывать несколько сканеров на одном потоке две причины:?.

  1. При закрытии сканера, вы автоматически закрывает основной поток Это означает, что если вы затем попытаетесь открыть/использовать другой сканер на поток, он будет терпеть неудачу, когда вы попытаетесь прочитать из закрытого потока. Потоки не могут будет вновь открыта.

  2. Даже если вы не закрываете сканер/поток, создание второго сканера в потоке, вероятно, приведет к проблемам. Сканер должен читать дальше, чтобы выяснить, где находятся границы токена. Затем он удерживает символы с открытым текстом во внутреннем буфере. Каждый сканер имеет свой собственный буфер. Поэтому, если у вас есть два или более сканера для одного потока и чередование их использования, один сканер может «захватить» символы, которые нужен другому сканеру.

+0

Не писать новый код для старых java-версий - это очень хороший момент, хотя основное исключение из этого стоит отметить: андроид до недавнего времени не поддерживал расширения java 1.7, поэтому вы можете избежать их, если таргетинг на Android (если у вас нет выбора аппаратного обеспечения). – Jules

+0

Хорошая точка ... обновлено. –

2

Закрытие сканера закрывает входной поток, который был создан с использованием. В вашем случае это System.in. Этот поток является особым случаем: он открывается средой перед запуском вашей программы и поэтому обычно не должен закрываться вашей программой.

В этом случае не стоит закрывать сканер. Просто позвольте сборщику мусора справиться с этим.

Смежные вопросы