Почему я не могу просто создать еще один объект сканера после использования scan.close()?

После использования метода scan.close() я не могу открыть другой сканер. Я искал свой вопрос в Google, чтобы найти только людей, предлагающих решение для обходного пути. Я просто хочу понять, почему это проблема в первую очередь. кто-нибудь может объяснить, почему?

import java.util.Scanner;

public class Main {

    public static Scanner scan = new Scanner(System.in);

    public static void main(String[] args) {
        scan.close();

        Scanner scan = new Scanner(System.in);

        System.out.println(scan.next());  //NoSuchElementException
    }

}

Я понимаю, что одновременное открытие нескольких сканеров может привести к ошибке outOfMemoryError, поэтому я подумал, почему бы не использовать его как одноэлементный служебный класс, из которого вы можете вызывать методы? Этот класс будет открывать и закрывать сканер при каждом использовании, чтобы потоки не оставались открытыми.

public class Main {

    public static void main(String[] args) {
        LinkedList<Scanner> list = new LinkedList<>();
        while(true) {
            list.add(new Scanner(System.in)); //OutOfMemoryError
        }
    }
}

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


person PanderIT    schedule 05.10.2019    source источник
comment
Можно, но вы закрыли System.in, так что вы ничего не можете с него прочитать. Вопрос в том, зачем его вообще закрывать? Если вам понадобится еще один, почему бы не использовать тот же самый?   -  person user207421    schedule 05.10.2019
comment
Я просто просто хочу ради исследования. Я уже знаю, как использовать тот же самый. Я просто изучаю класс Scanner и то, как он работает, и почему я не могу повторно открыть System.in после его закрытия.   -  person PanderIT    schedule 09.10.2019


Ответы (1)


Из документации для Scanner.close() :

если его базовый readable также реализует интерфейс Closeable тогда будет вызван метод readable close.

Поэтому, когда вы закрываете сканер, он также закрывает System.in, что означает, что вы не сможете позже создать из него новый сканер, так как вы не сможете повторно открыть поток после его закрытия.

И вы получаете OutOfMemoryError во втором примере только потому, что пытаетесь выделить бесконечное количество сканеров и предотвратить их сборку мусора, а не потому, что сканеры особенно тяжеловесны.

person Joseph Sible-Reinstate Monica    schedule 05.10.2019
comment
Я добавил пример для OutOfMemoryError, чтобы показать, что можно было бы повысить эффективность, если бы можно было открывать и закрывать сканер, когда это необходимо, а не держать его открытым, пока программа не завершит выполнение. Итак, вы говорите, что проблема заключается не в методе scan.close(), я получаю исключение NoSuchElementException, потому что после закрытия System.In я не могу повторно открыть другой поток System.in. - person PanderIT; 05.10.2019
comment
Это бессмысленно. И я говорю, что проблема в методе scan.close(). - person Joseph Sible-Reinstate Monica; 05.10.2019
comment
он также закрывает System.in, что означает, что вы не сможете позже создать из него новый сканер, поскольку вы не можете повторно открыть поток после его закрытия. Почему мы не можем открыть новый поток, когда он закрыт? - person PanderIT; 05.10.2019
comment
Я ценю ваши усилия в руководстве @Joseph Sible. ваш ответ дал мне новый вопрос и заставил меня искать дополнительные ответы, я нашел другой источник. stackoverflow.com/questions/27286690/ - person PanderIT; 05.10.2019
comment
@PanderIT Вы не можете повторно открыть закрытый поток, потому что для него нет API. - person user207421; 05.10.2019