--/--/--

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

2008/04/11

開けたものは閉める

ref:間違え探し

思わぬところで議論されてたんだけど、これ結構普通だと思ってたんだけどな。コメントにも書いたけどやりたいことは単純。開けたもの使い終わったら、必ず閉めましょう、ということだけ。Java で「必ず何かする」ということをするには finally を使うのが一番簡単で確実な方法。

try-catch-finally が入り乱れて、慣れない時はよく忘れるコード片ではある。だけども、finally でこういうことをしなければならない言語では、このロジックは必ず覚えておかなければならないものの1つだと思う。

で、具体的にどうするのかというお話し。先の記事では Connection が話題の対象になっていたけど、今回はコードを簡単にするため FileWriter を使う。開けて使って閉めるオブジェクトならなんでもいいので。

次のコードは各操作で発生する例外をそれぞれで catch する。すげー読みにくいけど、一番柔軟ではある。

try {
    FileWriter fw = new FileWriter("hoge");
    try {
        fw.write("fuga");
    } catch (IOException e) {
        System.err.println("write で失敗こいたよ");
    } finally {
        try {
            fw.close();
        } catch (IOException e) {
            System.err.println("close で失敗こいたよ");
        }
    }
} catch (IOException e) {
    System.err.println("new で失敗こいたよ");
}

個人的にこれはやりすぎだと思ってるので、俺は大体次のようにやる。先の記事と同じやりかた。

try {
    FileWriter fw = new FileWriter("hoge");
    try {
        fw.write("fuga");
    } finally {
        fw.close();
    }
} catch (IOException e) {
    System.err.println("どっかで失敗こいたよ");
}

問題としてはどの時点で投げられた例外なのか分からないということ。そういう判断がしたいなら、1つ目のコードみたいに律義に try-catch で囲ってやらなければならない。必要でない時はこれで済ませる。

finally での null チェックは必要ないのかというお話しは、結論から言うと必要ない。この例でいう fw が null である可能性は、new FileWriter で失敗したとき以外ありえない。では、new FileWriter で失敗するということはどういうことかというと、new FileWriter で IOException が投げられる場合である。new FileWriter 実行時に IOException が投げられれば、そのまま catch 節へと制御が移るので、入れ子になった try-finally 節には入らない。そもそも開いてすらいないので、閉じる必要がない。

あとコメントの返事したときには気づかなかったんだけど、ASIP さんのコードはやっぱりコンパイルエラーになるかと。その Connection の宣言位置だと finally からは見えない。それから close で投げられる例外がチェックされていない(throws してるとかいうのは無し)。もういっちょ付け加えれば、2回目の close に空の finally があるけど、これは全く意味が無い。試してみるといいです。

スポンサーサイト

comment

post




上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。