Java Tips:クリーンアップ処理をきれいに実装するには?:JAVA Developer
堅牢なアプリケーションを目指す際に、エラーや状態のチェック、適切なクリーンアップ、リカバリは重要なポイントになります。このTipsでは、クリーンアップ処理について覚えておきたいテクニックを紹介します。
クリーンアップはtry-catchをうまく使う
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
Javaプログラミングではメモリ管理を意識するケースは非常に少ないといえますが,ファイルやネットワーク,データベースなどシステムリソースの多くは,適切なクリーンアップをしなければなりません。ついメモリと同じ感覚でほったらかしにしておくと,すぐにメモリリークと同じ状態に陥ります。
たとえば,ファイルを開いたあとで何らかの処理を行い,不都合があった場合はファイルを閉じてメソッドから戻ります。次のようなコードになります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
ここで,チェックする内容が複数ある場合,if文を複数列挙することになるでしょう。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
チェックの論理式を反転させて記述するスタイルもありますが,多かれ少なかれこのようなスタイルになります。そして,このようなスタイルに記述上の冗長性を感じている読者も少なくないと思います。しかし,ここに潜むのは冗長性の問題だけでなく,チェック項目が増えて追加したときに,追加したif文にだけcloseメソッド呼び出しを忘れたりします。つまり,ポイントはクリーンアップ処理が複数に分散することです。
catchは不要
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
このようなとき,Javaではtry-catchを使うとスマートに記述できます。正確には,catchを利用せずに,try-finallyを利用します。具体的には,次のように記述します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
一般的にtryとくればcatchを思い浮かべますが,catchを抜かしてfinallyを書くことができます。そのため,クリーンアップ処理が必要なケースでは,finallyを有効活用するとよいでしょう。これが今回のTipsのポイントです。
なお,このケースでは,new FileInputStreamに対する例外をどうするのかが気になると思いますが,それは別のtry-catchで処理します。クリーンアップが不要な段階の例外は,このブロック(メソッド)から外に投げてしまいます。それに関連してもう少し考えてみましょう。
2重にクリーンアップが必要なケース
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
たとえばファイルコピーを行う場合のように,クリーンアップの必要なリソースを2つ以上確保して,それらの解放について考えなくてはならないことがあります。このような場合にもfinallyによるクリーンアップが有効です。
ただし,処理が複雑になれば複雑になるほど,コードはシンプルにすべきです。複数のシステムリソースを1つのメソッドの中で処理すると,ともすれば片一方だけ解放を忘れたり,まだ確保していないリソースを解放してしまったりします。
複数のクリーンアップが必要なケースは,潔く別のメソッドにしてしまうといいでしょう。次のようなコードになります。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
この例で見ると,ファイルコピーを行うdoFileCopyメソッドがIOExceptionを投げることは何も不自然ではありません。その代わりに,メソッド内の不測の事態に関しては責任を持つということです。
ここでは簡単な例で紹介しましたが,ポイントはcatchがなくてもfinallyを使えるという点です。非常に単純ですが,意外と忘れられがちなテクニックです。ぜひ覚えておいてください。
「JAVA Developer」より毎週役立つJava Tipsを配信中。ほかにも参考になるTipsは、JAVA Developerサイトのバックナンバーから探すことが可能です。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
Copyright(C) 2010 SOFTBANK Creative Inc. All Right Reserved.