Преимущества Java7 с ресурсами

Я смотрел новую функцию Java7. Я нашел, что try-with-resources Statement. Может ли кто-нибудь сказать мне, что именно это означает? Почему и где мы должны использовать его и где мы можем воспользоваться этой возможностью? Даже оператор try пропускает блок catch, который запутывает меня.

Ответ 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());
        }