2017-02-04 26 views
5

Czy obowiązkowe jest umieszczanie wewnętrznych try-for-resources, czy wszystko w jednym z try-for-resources zostanie automatycznie zamknięte?Czy obowiązkowe jest umieszczanie wewnętrznych try-for-resources, czy wszystko w jednym z try-for-resources zostanie automatycznie zamknięte?

try (BasicDataSource ds = BasicDataSourceFactory.createDataSource(dsProperties)) { 

     // still necessary for Connection to close if inside 
     // try-with-resources? 
     try (Connection conn = ds.getConnection()) { 

      String sql = "SELECT * FROM users"; 
      try (PreparedStatement stmt = conn.prepareStatement(sql)) { 

       try (ResultSet rs = stmt.executeQuery()) { 

        while (rs.next()) { 
         System.out.println(rs.getString("email")); 
         System.out.println(rs.getString("password")); 
        } 

       } 
      } 

     } 

    } catch (SQLException e) { 

     e.printStackTrace(); 
    } catch (Exception e) { 

     e.printStackTrace(); 
    } 
+1

dlaczego używasz wielu 'try-z-zasobami', użyj tylko jednego i umieść wiele instrukcji używając'; '. I zajmie się zamknięciem wszystkiego. –

+1

dziękuję @jack jay, dokładnie to chciałem wiedzieć – DevDio

Odpowiedz

4

W try-with-zasobów bloku, tylko środki z rachunku try zostanie automatycznie zamknięte przez try-with-zasobów konstruktu. Inne zasoby w tym bloku nie są powiązane i muszą być zarządzane (*).

Jednak można umieścić wiele zasobów w rachunku try, zamiast używać wielokrotność try-with-zasobów (po jednym dla każdego zasobu), na przykład:

try (PreparedStatement stmt = conn.prepareStatement(sql); 
    ResultSet rs = stmt.executeQuery()) { 
    while (rs.next()) { 
     System.out.println(rs.getString("email")); 
     System.out.println(rs.getString("password")); 
    } 
} 

(*) Jako @alexander-farber szpiczasty W komentarzu są również zasoby, które są automatycznie zamykane przez inny mechanizm, na przykład ResultSet zostaje zamknięty, gdy Statement, który je wygenerował, zostaje zamknięte. Chociaż nie zarządzasz tymi zasobami w sposób jawny, są one zarządzane przez ich implementację.

+0

Twoja instrukcja "Tylko zasoby w instrukcji try zostaną automatycznie zamknięte" jest błędna, ponieważ [Obiekt ResultSet jest automatycznie zamykany przez obiekt Statement, który go wygenerował] (https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html#close%28%29). –

+1

@AlexanderFarber dobry punkt. To pytanie dotyczy mechanizmu try-with-resources. Masz rację, że 'ResultSet' zostaje zamknięty, gdy' Statement' zostaje zamknięty, ale nie jest tak ze względu na try-with-resources. Wyjaśniłem swoją odpowiedź, dziękuję za wskazanie tego. – janos