- PR -

JavaTIPS 「データベースに接続したら後始末は確実に」に関して

投稿者投稿内容
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-12-26 14:36
訂正後のソースが
引用:

コード:
}
catch(SQLException e){ System.out.println(e); }
finally { // 例外の有無・種類に限らず後続を実行
  try{
    if(stmt != null) // Statementオブジェクトが生成済み?
      try{
        stmt.close();  // StatementオブジェクトとJDBCリソースの解放
      }
      catch(SQLException e){ System.out.println(e); }
    if(conn != null) // Connectionオブジェクトが生成済み?
      conn.close();  // Connectionオブジェクト解放,JDBCリソースの解除
  }
  catch(SQLException e){ System.out.println(e); }
}




となりましたね。(部分抜粋)
確かに漏れはなくなりましたが…

引用:

mioさんの書き込み (2006-12-25 21:26) より:
んー…。
コード:
} finally {
    if (stmt != null) try { stmt.close(); } catch (SQLException e) {}
    if (conn != null) try { conn.close(); } catch (SQLException e) {}
}


かなー。


と例示されているのにスルーされたのでしょうか。

そして
catch(SQLException e){ System.out.println(e); }
に対する突っ込みもスルーなのですね。

本文には手が入っていない様子ですから後始末の際のfinally節内での
try〜catchの際の注意事項などは注意喚起する気がないということでしょうか。
koe
大ベテラン
会議室デビュー日: 2003/07/13
投稿数: 198
投稿日時: 2006-12-26 17:21
おおよそmioさんの例通りだと思いますよ?
それに、mioさんの例どおりだと例外を握りつぶすことになるので、
その辺をふまえての修正かと思います。

例外処理がSystem.out.println(e)なのは、私も変だと思いますね。
せめてe.printStackTrace()なら…なんか他の方と意見がかぶりますが。

ただ、そこまで突っ込むなら、「例外処理は確実にログへ」のような
別のTIPSにまとめた方がいいと思いました。
例外処理は、ここ以外でもときおり議論になりますからね。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-12-26 17:46
引用:

koeさんの書き込み (2006-12-26 17:21) より:
おおよそmioさんの例通りだと思いますよ?
それに、mioさんの例どおりだと例外を握りつぶすことになるので、
その辺をふまえての修正かと思います。



どういう意味で言っておられます?
「mio氏のコードだとclose()の例外を握りつぶすので、
記事のコードはそうならないように修正されている」
という意味でしょうか?

記事のコードも例外を握りつぶしているので「修正」とは言えません。
また、try〜catchがネストする記述になっていますが、
このネストは無駄なのでこの点も「修正」とは言えません。
mio氏のように併記する記述が一般的だと思われます。

mio氏のコードではcatch節内が空なのをSystem.out.println()にしたことを
指して「修正」と言っておられるのでしょうか?


上位の例外を生かすために敢えてfinally内で発生する例外を握りつぶす
という話は、006-12-25 21:49の私の発言および、
2006-12-26 07:34のかつのり氏の発言でされていますよね。

ただし、意図して例外を握りつぶすというのは特殊な例で、
今回の話題であるConnectionのclose()や、I/OのStreamのclose()が
その具体例だ、という話でした。

そして、記事にはそのあたりの事情に対する説明がないのですね、
というのが私の指摘でした。

一番外の、メインのtry〜catchについて言えば、koe氏のおっしゃる
ログ出力の話題へと繋がるのですが、finally節内でのclose()の
try〜catchでは事情が異なるので分けて議論しなければなりませんね。
koe
大ベテラン
会議室デビュー日: 2003/07/13
投稿数: 198
投稿日時: 2006-12-26 19:19
引用:

nagiseさんの書き込み (2006-12-26 17:46) より:
どういう意味で言っておられます?


うっかりしてました。コードを改めてみたらおっしゃるとおり。
stmt.close()で例外が発生するとcon.close()しないで終わりますね。
申し訳ない。
せん
ぬし
会議室デビュー日: 2002/03/04
投稿数: 397
投稿日時: 2006-12-26 21:52
議論をさまたげるわけではありませんが、提案しているのに直してくれないのか、
という方向に行ってしまうのは残念ですので、ここで引用。

引用:

また、今回のように@IT内の記事でWebページがうまく表示されない、間違いを見つけた、
もしくは記事の内容に疑問がある、こんな記事が読みたい、記事を書いてみたい、
などについては編集部(info@atmarkit.co.jp)までお問い合わせください。



ですので、こちらの問い合わせてみてはいかがでしょうか?
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-12-26 22:05
しかし、
コード:
catch(SQLException e){ System.out.println(e); } 


これは酷い。

記事の対象が初心者だと思うのですが、
大体初心者ってサンプルコードをコピペで使うんですよね。
なので、あまりプログラムの本質ではない部分ではあるのですが、
こういうところで手を抜くべきではないかと。

丁寧に書く気がなくても、せめて
コード:
catch(SQLException e){
    ...//適切な例外処理
} 


みたいに省略するのがいいと思うんですよね。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2006-12-27 09:53
ohirata氏こと@IT編集部の記事編集担当の平田氏が
こちらのスレッドで返答されていたのでそのまま話が続いていますが
別途依頼をだすべきなのでしょうか?

1.サンプルコードが正しく後始末できていないものだった
  (現時点で一応は漏れることはないが綺麗なサンプルではない)
2.メインのtry-catch-finallyのcatch節の処理について
  なんらのコメントもない。該当サンプルコードでは省略しているが
  本来はエラー時の処理を記述する必要がある旨を明示すべきではないか
3.メインのfinally節の中でのclose()に対してのtry-catchでは
  外側のtry-catch-finally節での処理を生かすために
  遭えて例外を握りつぶすが、その特殊事情についての説明がない

というのが今のところの指摘内容ですね。

編集部側の事情は我々にはよく分かりませんが、
不適切なサンプルや記事が掲載されたままでは
掲載側、参照する側、双方に不利益があるので
どうにかして欲しいと願っています。
せん
ぬし
会議室デビュー日: 2002/03/04
投稿数: 397
投稿日時: 2006-12-27 10:42
私も編集部側の事情はわかりません。
引用:

nagiseさんの書き込み (2006-12-27 09:53) より:
ohirata氏こと@IT編集部の記事編集担当の平田氏が
こちらのスレッドで返答されていたのでそのまま話が続いていますが
別途依頼をだすべきなのでしょうか?


今回、返答された件については、特例と思った方が良くないですかね?

このようなサンプルの方がふさわしいよね、という議論であれば、
このスレッドはふさわしいとおもうのですが、同時に編集部側への要望を
ここでやる、というのはどうなんだろうか?と思う訳です。
まさか、運営側に掲示板を全てチェックしろ、とはいえないでしょうし。
# 運営側に立ってみれば分かりますよね。

この掲示板のユーザ間でのやり取りでもそうですが、窓口があるのであれば、
そこへ問い合わせるのがスジとおもいますので、修正の依頼については
前述の窓口へ問い合わせるのがよろしいかとおもいますよ。

スキルアップ/キャリアアップ(JOB@IT)