Должен ли я объявлять КАЖДЫЙ ресурс в заявлении try-with-resources?

Во многих примерах попытки с ресурсом, которые я искал, Statement и ResultSet объявляются отдельно. Как упоминалось в документе Java, методы закрытия ресурсов вызываются в порядке, обратном их созданию.

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

} catch (Exception e) {

}

Но теперь у меня есть несколько запросов в моей функции.

Могу ли я сделать Statement и ResultSet всего одной строкой? Мой код выглядит так:

try (ResultSet rs = con.createStatement().executeQuery(sql);
     ResultSet rs2 = con.createStatement().executeQuery(sql2);
     ResultSet rs3 = con.createStatement().executeQuery(sql3)) {

} catch (Exception e) {

}

Если я объявлю их только в одной строке, закроет ли он ресурс как ResultSet, так и Statement?


person edyucheng    schedule 22.03.2019    source источник


Ответы (2)


Если вы внимательно посмотрите, то увидите, что эта концепция называется try-with-resources.

Обратите внимание на множественное число! Вся идея заключается в том, что вы можете объявить один или несколько ресурсов в одном операторе, и jvm гарантирует правильную обработку.

Другими словами: когда ресурсы семантически связаны друг с другом, рекомендуется объявлять их вместе.

person GhostCat    schedule 22.03.2019
comment
con.createStatement().executeQuery(sql2); создает объект Statement и объект ResultSet. Означает ли это, что ресурсы обоих операторов и объектов ResultSet семантически связаны друг с другом, и оба ресурса будут автоматически закрыты? - person edyucheng; 22.03.2019
comment
@edyucheng Да, когда они вместе, это кажется разумным. Но, пожалуйста, поймите, что такие детали действительно зависят от вашего общего дизайна/контекста. Кроме того, спасибо за быстрый прием ;-) - person GhostCat; 22.03.2019

Да, и это работает именно так, как вы указали в своем вопросе, несколько утверждений, разделенных точкой с запятой.

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

 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());
    }
}

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

ResultSet реализует AutoCloseable, что означает, что попытка с ресурсами также принудительно закроет его, когда он закончит его использовать.

https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html

person mjuarez    schedule 22.03.2019