Я смотрел новую функцию Java7. Я нашел, что try-with-resources Statement. Может ли кто-нибудь сказать мне, что именно это означает? Почему и где мы должны использовать его и где мы можем воспользоваться этой возможностью? Даже оператор try
пропускает блок catch
, который запутывает меня.
Преимущества Java7 с ресурсами
Ответ 1
Он был введен из-за того, что некоторые ресурсы, используемые в Java (например, SQL-соединения или потоки), трудно обрабатывать должным образом; в качестве примера, в java 6 для обработки InputStream, вам нужно было сделать что-то вроде:
InputStream stream = new MyInputStream(...);
try {
// ... use stream
} catch(IOException e) {
// handle exception
} finally {
try {
if(stream != null) {
stream.close();
}
} catch(IOException e) {
// handle yet another possible exception
}
}
Вы заметили, что уродливая двойная попытка? теперь с помощью try-with-resources вы можете это сделать:
try (InputStream stream = new MyInputStream(...)){
// ... use stream
} catch(IOException e) {
// handle exception
}
и close() автоматически вызывается, если он генерирует исключение IOException, он будет подавлен (как указано в Java Language Спецификация 14.20.3). То же самое происходит для java.sql.Connection
Ответ 2
Оператор try-with-resources - это оператор try, который объявляет один или больше ресурсов. Ресурс - это объект, который должен быть закрыт после программа заканчивается им. Оператор try-with-resources гарантирует, что каждый ресурс будет закрыт в конце инструкции. Любые объект, реализующий
java.lang.AutoCloseable
, который включает все объекты, которые реализуютjava.io.Closeable
, могут использоваться как ресурс.В следующем примере читается первая строка из файла. Он использует экземпляр BufferedReader для чтения данных из файла. BufferedReader это ресурс, который должен быть закрыт после завершения программы это:
static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } }
В этом примере ресурс, объявленный в try-with-resources оператор - BufferedReader. Появится выражение о декларации в скобках сразу после ключевого слова try. Класс BufferedReader, в Java SE 7 и более поздних версиях, реализует интерфейс java.lang.AutoCloseable. Поскольку экземпляр BufferedReader объявленный в заявлении try-with-resource, он будет закрыт независимо от того, завершает ли оператор try нормально или резко
Здесь вы можете прочитать больше .
Ответ 3
В Java, если вы используете ресурс, такой как входной или выходной поток, вам всегда нужно закрыть его после использования. Он также может генерировать исключения, поэтому он должен находиться в блоке try
catch
. Закрытие должно быть в блоке finally
. Это, по крайней мере, путь до Java 7. Это имеет несколько недостатков:
- Вам нужно будет проверить, если ваш ресурс
null
перед закрытием - Закрытие может вызывать исключения, поэтому ваш
finally
должен был содержать еще одинtry
-catch
- Программисты, как правило, забывают закрыть свои ресурсы.
В то время как первые два являются в основном проблемами синтаксиса, последний имеет более важное значение. Поэтому, если вы используете инструкцию try-with, ваш код становится намного чище и, самое главное, ваш ресурс всегда будет закрыт: -)
Ответ 4
Преимущество заключается в том, что вам не нужно явно закрывать ресурсы, определенные вами в заявлении try-with-resources. JVM позаботится об этом. Он автоматически закроет эти ресурсы для вас.
В целом проблемы, с которыми сталкиваются разработчики разработчиков, - это структурировать блоки try-catch-finally, потому что даже в конце блока, где мы закрываем ресурсы, мы должны использовать try-catch. Существуют различные структуры заявления try-catch-finally, чтобы помочь решить эту проблему, но выражение try-with-resources в основном поможет вам упростить логику структуры кодирования.
Ответ 5
Обновление с 2017 года после выпуска Java 9
Теперь с Java 9
у нас больше синтаксического сахара, и у нас может быть ресурс, объявленный вне блока try-catch
, но все же обработанный правильно.
Возьмем, например, этот способ Java 6
для обработки ресурса:
InputStream stream = new MyInputStream(...);
try {
// ... use stream
} catch(IOException e) {
// handle exception
} finally {
try {
if(stream != null) {
stream.close();
}
} catch(IOException e) {
// handle yet another possible exception
}
}
Здесь мы можем заметить, что этот код невероятно уродлив, как указано в других ответах.
Итак, решение в Java 7
должно было ввести это try-catch-with-resource
:
try (InputStream stream = new MyInputStream(...)){
// ... use stream
} catch(IOException e) {
// handle exception
}
Эти обозначения, безусловно, лучше, чем предыдущие, однако у нас есть проблема. Если ресурс (strem в этом случае) был объявлен ранее, но мы хотим быть уверены, что он правильно обработан в этом блоке, нам нужен трюк, подобный этому:
InputStream stream = new MyInputStream(...)
try (InputStream stream2 = 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, введя новый синтаксис:
InputStream stream = new MyInputStream(...)
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. Единственное ограничение заключается в том, что переменная считывателя должна быть эффективной или окончательной.
Ответ 6
Преимущества использования Попробуйте использовать ресурсы
-
Более читаемый код и легко писать.
-
Автоматическое управление ресурсами.
-
Количество строк кода уменьшается.
-
Не нужно, наконец, блокировать только для закрытия ресурсов.
-
Мы можем открыть несколько ресурсов в инструкции try-with-resources, разделенных точкой с запятой. Например, мы можем написать следующий код.
-
Когда несколько ресурсов открыты в try-with-resources, он закрывает их в обратном порядке, чтобы избежать какой-либо проблемы с зависимостью. Вы можете расширить мою программу ресурсов, чтобы доказать это.
public void sampleTryWithResource() {
try(Connection dbCon = DriverManager.getConnection("url", "user", "password");
BufferedReader br = new BufferedReader(new FileReader("C://readfile/input.txt"));) {
//...Your Business logic
} catch (Exception e) {
//...Exception Handling
}
}
Ответ 7
Как насчет этого - если ресурс инициализирован внутри try {} is'nt, он автоматически закрывается?
try {
Scanner scanner = new Scanner(new File(csvFile));
while (scanner.hasNext()) {
// do something
}
scanner.close();
}catch(FileNotFoundException fnfe)
{
System.err.println(fnfe.getLocalizedMessage());
}