Квот Javadoc :
Потоки имеют метод BaseStream.close () и реализуют AutoCloseable, но практически все экземпляры потоков на самом деле не нужно закрывать после использования. Как правило, закрывать будут только те потоки, источником которых является канал ввода-вывода (например, те, которые возвращены Files.lines (Path, Charset)). Большинство потоков поддерживаются коллекциями, массивами или генерирующими функциями, которые не требуют специального управления ресурсами. (Если поток требует закрытия, он может быть объявлен как ресурс в инструкции try-with-resources.)
«Почти все» и «в целом» являются расплывчатыми - если вы пишете библиотеку и абстрагируете источник вашего потока от пользователей этого потока, то вам все равно придется задать себе вопрос - «должен ли я закрыть это?" Потоки, поддерживаемые IO, должны быть закрыты, потому что терминальные операции не вызывают close
, поэтому мне всегда нужно либо помнить / документировать, откуда поступает мой поток, либо я всегда должен close
это делать .
Ядерная опция, я думаю, состояла бы в том, чтобы не возвращать Streams из методов или принимать параметры Stream, что является мнением, которое повторяют некоторые люди из команды JDK. Я считаю это чрезмерным ограничением, учитывая практическую полезность потоков.
Каковы ваши лучшие практики закрытия потоков? Я искал в Интернете ответ на этот вопрос от некоторых людей из JDK, которые обычно работают над похожими вопросами сообщества, но не находят ничего актуального.
Ответы:
Как вы сказали, в Java вам нужно точно знать, кто отвечает за освобождение того или иного ресурса, чтобы вы могли вставить соответствующие конструкции try-catch-, try-with-resources или как-то делегировать эту задачу.
Единственное, что вы можете рассчитывать на очистку GC - это 100% чистая память.
Если могут быть смешаны какие-то другие ресурсы, единственное, что вы можете разумно сделать, это просто не рисковать.
источник
close
это единственная безопасная альтернатива? Я предполагаю, что вопрос состоит в том, чтобы не делать код слишком уродливым каждый раз, когда было бы удобно использовать Stream.Что касается «лучших практик», я думаю, что было бы неплохо использовать соглашение об именах для методов, которые возвращают «потоки ресурсов».
Если необходимо редактировать поток
close()
, вызовите метод фабрикиopen()
илиopenStream()
. Вызовите методы, которыеstream()
создают эфемерные потоки в соответствии с соглашением, установленным SDK. Всегда ставьте javadoc на метод, чтобы предупредить клиента, что он долженclose()
это сделать.Я бы хотел, чтобы авторы SDK не выбрали вариант
AutoCloseable
базового потока. ОтдельныйResourceStream
подтип, который тривиально реализуетAutoCloseable
, сделал бы разные контракты очевидными. Тогда вы не сможете закрыть объект,Stream
который ему не нужен, и вы можете обнаружить потенциально неправильноResourceStream
управляемые инструменты статического анализа.В зависимости от потребностей вашей кодовой базы (и вашей способности обеспечивать соблюдение соглашений при проверке кода), вы можете сами создать подкласс потокового типа. Или, если вы хотите создать свои собственные инструменты статического анализа, аннотацию метода, которая помечает управляемые ресурсы напрямую.
источник