What's the purpose of try-with-resources statements?
Какова цель инструкций try-with-resources?
В Java 7 появилась новая функция под названием try-with-resources. Что это? Почему и где мы должны ее использовать и где мы можем воспользоваться преимуществами этой функции?
В try инструкции нет catch блока, который меня смущает.
Переведено автоматически
Ответ 1
Это было введено из-за того, что некоторые ресурсы, используемые в Java (например, SQL-соединения или потоки), трудно обрабатывать должным образом; например, в java 6 для правильной обработки InputStream вам нужно было сделать что-то вроде:
и close() вызывается автоматически, если он вызывает исключение IOException , оно будет подавлено (как указано в спецификации языка Java 14.20.3) . То же самое происходит для java.sql.Connection
Инструкция try-with-resources - это инструкция try, которая объявляет один или несколько ресурсов. Ресурс - это объект, который должен быть закрыт после завершения работы с ним программы. Инструкция try-with-resources гарантирует, что каждый ресурс будет закрыт в конце инструкции. Любой объект, который реализует java.lang.AutoCloseable, который включает все объекты, которые реализуют java.io.Closeable, может использоваться в качестве ресурса.
В следующем примере считывается первая строка из файла. Для чтения данных из файла используется экземпляр BufferedReader . BufferedReader - это ресурс, который должен быть закрыт после завершения работы с ним программы:
В этом примере ресурс, объявленный в инструкции try-with-resources , является BufferedReader . Инструкция declaration появляется в круглых скобках сразу после ключевого слова try . Класс BufferedReader в Java SE 7 и более поздних версиях реализует интерфейс java.lang.Автоматически закрываемый. Поскольку экземпляр BufferedReader объявлен в инструкции try-with-resource , он будет закрыт независимо от того, завершается ли инструкция try обычным образом или внезапно
Теперь с Java 9 у нас больше синтаксического сахара, и мы можем иметь ресурс, объявленный вне try-catch блока, но все еще обрабатываемый должным образом.
Давайте возьмем для примера этот Java 6 способ обработки ресурса:
Эта нотация, безусловно, намного лучше предыдущей, однако у нас есть проблема. Если ресурс (в данном случае поток) был объявлен ранее, но мы хотим быть уверены, что он правильно обрабатывается в этом блоке, нам нужен трюк, подобный этому:
InputStreamstream=newMyInputStream(...) try (InputStreamstream2= stream) { // do something with stream being sure that is going to be closed at the end } catch(IOException e) { // handle exception }
Мы можем заметить, что эта ситуация может быть решена только с помощью другого фрагмента уродливого кода. Вот почему в Java 9 функция Try-With-Resources была улучшена, был введен новый синтаксис:
InputStreamstream=newMyInputStream(...) try (stream) { // do something with stream being sure that is going to be closed at the end } catch(IOException e) { // handle exception }
Обратите внимание, что этот синтаксис приведет к ошибке времени компиляции для Java версии 8 или меньшей
Это более "естественный" способ написания, хотя в большинстве случаев использования нам не нужен ресурс вне области действия блока try . Единственное ограничение заключается в том, что переменная reader должна быть фактически final или просто final.
Ответ 4
В Java, если вы используете ресурс, такой как потоки ввода или вывода, вам всегда приходится закрывать его после использования. Он также может генерировать исключения, поэтому он должен быть в trycatch блоке. Закрытие должно быть в finally блоке . По крайней мере, так было до Java 7. У этого есть несколько недостатков:
Вам нужно будет проверить, работает ли ваш ресурс null перед его закрытием
Само закрытие может вызывать исключения, поэтому ваше finally должно было содержать другое try - catch
Программисты, как правило, забывают закрыть свои ресурсы
Хотя первые две в основном связаны с проблемами синтаксиса, последняя более критична. Итак, если вы используете инструкцию try-with, ваш код становится намного чище и, самое главное, ваш ресурс всегда будет закрыт :-)