2014-05-16 28 views
2

在此Java程序示例:試穿與資源語句的Java

package test; 

import java.sql.DriverManager; 
import java.sql.Connection; 
import java.sql.Statement; 

public class Test 
{ 
    private static void example(){ 
     String url = "jdbc:oracle:thin:@//localhost:7856/xe"; 
     String user = "user"; 
     String password = "pass"; 
     try(Connection con = DriverManager.getConnection(url, user, password); 
      Statement stmt = con.createStatement()){ 
      throw new OutOfMemoryError("Error"); 
     }catch (SQLException e){ 
      System.err.println("SQLException"); 
     } 
    } 

    public static void main(String [] args){ 
     try{ 
      example(); 
     }catch (OutOfMemoryError e){ 
      System.err.println("OutOfMemoryError"); 
     } 
     // Rest of code here... 
    } 
} 

時,在靜態方法示例()的機構,OutOfMemoryError異常錯誤被拋出,是連接「CON」和聲明「stmt」在終止靜態方法example()之前自動關閉,儘管沒有任何「catch」捕獲這些錯誤,所以在main()的其餘代碼中確定這兩個對象是關閉的?

謝謝。

回答

4

是; try-with-resources結構總是關閉資源,即使它是一個未檢查的throwable(如OutOfMemoryError)。

這是在JLS 14.20.3中指定的,它以一個非常通用的語句開始,即資源「自動關閉」,但隨後會涉及資源關閉時的各種示例。基本上,任何非null資源是總是已關閉,就好像關閉已在爲該一個資源創建的try-finallyfinally子句中。即使在try中有多個資源(就像你的情況一樣)(「關閉一個資源時的異常並不妨礙關閉其他資源」)。

簡單的類來說明吧:

public class Twr { 
    private static class TwrCloseable implements AutoCloseable { 
    private final String id; 

    TwrCloseable(String id) { 
     this.id = id; 
    } 

    @Override 
    public void close() { 
     System.out.println("closing " + id); 
    } 
    } 

    public static void main(String[] args) { 
    try (TwrCloseable closeable1 = new TwrCloseable("first"); 
     TwrCloseable closeable2 = new TwrCloseable("second")) { 
     throw new OutOfMemoryError(); 
    } 
    } 
} 

輸出:

closing second 
closing first 
Exception in thread "main" java.lang.OutOfMemoryError 
    at Twr.main(Twr.java:19) 

注意,他們正在以相反的順序關閉; 「第二」在「第一」之前關閉。在你的例子中,這意味着StatementConnection之前關閉,這正是你想要的。