Описание тега try-with-resources

Оператор try-with-resources - это оператор try в Java, который объявляет один или несколько ресурсов. Ресурс - это объект, который необходимо закрыть после того, как программа завершит работу с ним. Оператор try-with-resources гарантирует, что каждый ресурс будет закрыт в конце оператора.

Заявление о попытках с ресурсами

В try-with-resourcesоператор - это оператор попытки, объявляющий один или несколько ресурсов. Ресурс - это объект, который необходимо закрыть после того, как программа завершит работу с ним. Вtry-with-resourcesоператор гарантирует, что каждый ресурс будет закрыт в конце оператора. Любой объект, реализующий java.lang.AutoCloseable, который включает все объекты, реализующие java.io.Closeable, может использоваться как ресурс.

В следующем примере считывается первая строка из файла. Он использует экземпляр BufferedReader для чтения данных из файла.BufferedReader - это ресурс, который необходимо закрыть после того, как программа завершит работу с ним:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br = Files.newBufferedReader(Paths.get(path))) {
        return br.readLine();
    }
}

В этом примере ресурс, объявленный в try-with-resources заявление - это BufferedReader. Оператор объявления появляется в круглых скобках сразу после ключевого слова try. КлассBufferedReaderв Java SE 7 и более поздних версиях реализует интерфейс java.lang.AutoCloseable. ПосколькуBufferedReader экземпляр объявлен в try-with-resource оператор, он будет закрыт независимо от того, завершился ли оператор try нормально или внезапно (в результате выполнения метода BufferedReader.readLine бросая исключение IOException).

До Java SE 7 можно было использовать блок finally, чтобы гарантировать, что ресурс закрыт, независимо от того, завершается ли оператор try нормально или внезапно. В следующем примере используется блок finally вместоtry-with-resources заявление:

static String readFirstLineFromFileWithFinallyBlock(String path)
                                                     throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }
}

Однако в этом примере, если методы readLine а также close оба выдают исключения, затем метод readFirstLineFromFileWithFinallyBlockвыбрасывает исключение из блока finally; исключение, выброшенное из блока try, подавляется. Напротив, в примереreadFirstLineFromFile, если исключения выбрасываются как из блока try, так и из try-with-resources оператор, затем метод readFirstLineFromFileвыбрасывает исключение из блока try; исключение, выброшенное изtry-with-resourcesблок подавлен. В Java SE 7 и более поздних версиях вы можете получать подавленные исключения; см. раздел "Подавленные исключения" для получения дополнительной информации.

Вы можете объявить один или несколько ресурсов в try-with-resourcesзаявление. В следующем примере извлекаются имена файлов, упакованных в zip-файл zipFileName, и создается текстовый файл, содержащий имена этих файлов:

public static void writeToFileZipFileContents(String zipFileName,
                                           String outputFileName)
                                           throws java.io.IOException {

    java.nio.charset.Charset charset =
         java.nio.charset.StandardCharsets.US_ASCII;
    java.nio.file.Path outputFilePath =
         java.nio.file.Paths.get(outputFileName);

    // Open zip file and create output file with 
    // try-with-resources statement

    try (
        java.util.zip.ZipFile zf =
             new java.util.zip.ZipFile(zipFileName);
        java.io.BufferedWriter writer = 
            java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
    ) {
        // Enumerate each entry
        for (java.util.Enumeration entries =
                                zf.entries(); entries.hasMoreElements();) {
            // Get the entry name and write it to the output file
            String newLine = System.getProperty("line.separator");
            String zipEntryName =
                 ((java.util.zip.ZipEntry)entries.nextElement()).getName() +
                 newLine;
            writer.write(zipEntryName, 0, zipEntryName.length());
        }
    }
}

В этом примере try-with-resourcesОператор содержит два объявления, разделенных точкой с запятой: ZipFile и BufferedWriter. Когда блок кода, который следует непосредственно за ним, завершается нормально или из-за исключения, методы закрытияBufferedWriter а также ZipFileобъекты автоматически вызываются в этом порядке. Обратите внимание, что закрывающие методы ресурсов вызываются в порядке, обратном их созданию.

В следующем примере используется try-with-resourcesоператор для автоматического закрытия объекта java.sql.Statement:

public static void viewTable(Connection con) throws SQLException {

    String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";

    try (Statement stmt = con.createStatement();
         ResultSet rs = stmt.executeQuery(query)) {

        while (rs.next()) {
            String coffeeName = rs.getString("COF_NAME");
            int supplierID = rs.getInt("SUP_ID");
            float price = rs.getFloat("PRICE");
            int sales = rs.getInt("SALES");
            int total = rs.getInt("TOTAL");

            System.out.println(coffeeName + ", " + supplierID + ", " + 
                               price + ", " + sales + ", " + total);
        }
    } catch (SQLException e) {
        JDBCTutorialUtilities.printSQLException(e);
    }
}

Ресурс java.sql.Statement используемый в этом примере является частью JDBC 4.1 и более поздних версий API.

Примечание: A try-with-resourcesОператор может иметь блоки catch и finally, как и обычный оператор try. Вtry-with-resources, любой блок catch или finally запускается после закрытия объявленных ресурсов.

Подавленные исключения

Исключение может быть вызвано из блока кода, связанного с try-with-resourcesзаявление. В примереwriteToFileZipFileContents, исключение может быть выброшено из блока try, и до двух исключений могут быть выброшены из try-with-resources заявление, когда он пытается закрыть ZipFile а также BufferedWriterобъекты. Если исключение выброшено из блока try и одно или несколько исключений выброшены изtry-with-resources оператор, то исключения, выброшенные из try-with-resources оператор подавляется, и исключение, созданное блоком, - это исключение, вызванное writeToFileZipFileContentsметод. Вы можете получить эти подавленные исключения, вызвавThrowable.getSuppressed из исключения, созданного блоком try.

Классы, реализующие интерфейс AutoCloseable или Closeable

См. Javadoc интерфейсов AutoCloseable и Closeable для получения списка классов, реализующих любой из этих интерфейсов. Интерфейс Closeable расширяет интерфейс AutoCloseable. Метод close интерфейса Closeable генерирует исключения типа IOException, в то время как метод close интерфейса AutoCloseable генерирует исключения типа Exception. Следовательно, подклассы интерфейса AutoCloseable могут переопределить это поведение метода close, чтобы генерировать специализированные исключения, такие как IOException, или вообще не исключать исключения.

Ссылки: http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html