2009-08-26 12 views
30

: - catchブロックを最後に内側 - まだ試して必要のtry-catch-最終的には、その後、再び、私は多くの場合のような状況に遭遇してきたトライキャッチ

try{ 
    ... 
    stmts 
    ... 
} 
catch(Exception ex) { 
    ... 
    stmts 
    ... 
} finally { 
    connection.close // throws an exception 
} 

これを克服するベストプラクティスは何ですか?

try { 
    try { 
     .. 
     stmts 
     ... 
    } 
    finally { 
     connection.close(): 
    } 
} catch (Exception ex) { 
    .. 
    stmts 
    ..  
} 

私は私のために、この配管の世話をしたライブラリを使用していなかったとき、私は通常はこれを使用:

+0

:これらの行のすべてを持っているJava 6のバージョンよりも、むしろ

public void java7() throws SQLException { try (Connection connection = Connections.openConnection(); CallableStatement callableStatement = connection.prepareCall("my_call"); ResultSet resultSet = callableStatement.executeQuery()) { while (resultSet.next()) { String value = resultSet.getString(1); System.out.println(value); } } } 

おそらく、リソースの獲得も同様にスローされます。 (実際にはセスの答えを使っています) –

答えて

23

クラスに、static closeQuietlyの例外をキャッチしてログに記録するメソッドを記述し、適切なものを使用します。

あなたはこのような何か読みになってしまいます:

public class SQLUtils 
{ 
    private static Log log = LogFactory.getLog(SQLUtils.class); 

    public static void closeQuietly(Connection connection) 
    { 
    try 
    { 
     if (connection != null) 
     { 
     connection.close(); 
     } 
    } 
    catch (SQLExcetpion e) 
    { 
     log.error("An error occurred closing connection.", e); 
    } 
    } 

    public static void closeQuietly(Statement statement) 
    { 
    try 
    { 
     if (statement!= null) 
     { 
     statement.close(); 
     } 
    } 
    catch (SQLExcetpion e) 
    { 
     log.error("An error occurred closing statement.", e); 
    } 
    } 

    public static void closeQuietly(ResultSet resultSet) 
    { 
    try 
    { 
     if (resultSet!= null) 
     { 
     resultSet.close(); 
     } 
    } 
    catch (SQLExcetpion e) 
    { 
     log.error("An error occurred closing result set.", e); 
    } 
    } 
} 

そして、あなたのクライアントコードのようなものになります:1つの以上試みを使用し躊躇しないでください

Connection connection = null; 
Statement statement = null; 
ResultSet resultSet = null; 
try 
{ 
    connection = getConnection(); 
    statement = connection.prepareStatement(...); 
    resultSet = statement.executeQuery(); 

    ... 
} 
finally 
{ 
    SQLUtils.closeQuietly(resultSet); 
    SQLUtils.closeQuietly(statment); 
    SQLUtils.closeQuietly(connection); 
} 
+8

これはこれまでの私の選択でもありますが、最近はapache commons DBUtilのようなクラスがあることがわかりました。 –

+0

は良いオプションのように見えます:)ありがとう – Ajay

10

私は通常、このようにそれをやりました。

Imagistが指摘しているとおり、これは技術的には最終的にキャッチ前に実行されるものと同じではありませんが、解決しようとしていた問題を解決すると思います。

+0

それは技術的には同じではありませんが、状況によってはアジェイが望むことができるかもしれません。 – Imagist

+0

@Imagist:良い点。私は私の答えを更新します。ありがとう。 – seth

+0

もちろん、Execute Aroundイディオムでそれを抽象化することもできます。 –

1

...最後にキャッチする。

-1

だけで一般的に使用すると、リソースを閉じるときに起こる例外をログ以上何もする必要はありませんので、それは本当にで行くべき

+0

あなたのポイントは? –

+0

あなたのポイントを得られなかった – Ajay

0

...最後に、常にどちらかの試みで実行するか、キャッチします。..覚えてそれ自身のtry/catch。しかし、これは頻繁に起こる一般的なコードなので、あなた自身を繰り返してはいけませんし、同じ方法で2つのtry/catch項目を持たないように静的メソッド(Nick Holtが示唆しているように)コードを読みやすく、フォローしやすくします。

+0

私はそれに同意できないと思います。私の考えでは、リソースを閉じることの失敗は、使用中に発生する典型的な例外よりも深刻な問題です。 1つは内部例外(vb.netではC#よりも簡単です)を維持するように努めるべきですが、「より厳しい」ものを投げるべきです。 – supercat

+0

ネットワークから読んでいて、完了している場合は、リソースが閉じられなかったという結果は本当ですか?それは確かにプログラムについて何も変わることはありません。 – Yishai

+0

ポートを開いたままにして他の誰にも使用できない場合を除き –

4

Commons-ioには、inおよび出力ストリーム用のcloseQuietly()もあります。私はいつもそれを使用しています。それはあなたのコードをもっと読みやすくします。

12

他の人が触れたように、静的なcloseQuietlyユーティリティがあります。あなたはjava.ioではなくjava.sqlの世界であるならば、まさにこの目的のために有用なインターフェースがあります - - 追加することの一つjava.io.Closeable

すべてのデータソースおよびシンクjava.ioには、このインタフェースを実装する - すべてのストリーム、チャンネル、作家を読者。そうすれば、多くのオーバーロードされたバージョンを必要とせずに同じ "例外(close)()"問題に対処するための単一のユーティリティを作成できます。

public class IoUtils { 

    public static closeQuietly (Closeable closeable) { 
    try { 
     closeable.close(); 
    } catch (IOException logAndContinue) { 
     ... 
    } 
    } 

} 
0

便利Closeables#closeQuitely方法では、Googleグアバライブラリでもあります - それは、任意の閉鎖可能

0

に使用することができ、我々は、後でそれにようやくボックとキャッチブロックに続くブロックを試してみることができますか?

1

だけで簡単なメモは、Java 7(および8)で、あなたが代わりに書くことができると言うこと:

public void java6() throws SQLException { 
    Connection connection = Connections.openConnection(); 
    try { 
     CallableStatement callableStatement = connection.prepareCall("my_call"); 
     try { 
      ResultSet resultSet = callableStatement.executeQuery(); 
      try { 
       while (resultSet.next()) { 
        String value = resultSet.getString(1); 
        System.out.println(value); 
       } 
      } finally { 
       try { 
        resultSet.close(); 
       } catch (Exception ignored) { 
       } 
      } 
     } finally { 
      try { 
       callableStatement.close(); 
      } catch (Exception ignored) { 
      } 
     } 
    } finally { 
     try { 
      connection.close(); 
     } catch (Exception ignored) { 
     } 
    } 
} 
関連する問題