2026年2月8日日曜日

【Java進化史 第1回】Java7 - try-with-resourcesは何を変えたのか?

【Java進化史 第1回】Java7 - try-with-resourcesは何を変えたのか?

Java7は地味だと言われる。

だが、現場を救った機能がある。

それが try-with-resources だ。


■ 昔のclose地獄

Java6まで、リソースを扱うコードはこうだった。


FileInputStream fis = null;
try {
    fis = new FileInputStream("test.txt");
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (fis != null) {
        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

何度これを書いただろう。

  • close忘れ
  • 二重try
  • ネスト地獄

そして一番怖いのは、 close忘れによるDB接続リークだ。

Javaから接続しているDBコネクションが解放されず、 接続数がMAXに達する。

ある日突然、全体が止まる。

原因は、たった一行のclose忘れ。

実際に、トラブルの火種になり得る。


■ JDBCコネクションプールとの関係

「でも今はコネクションプールがあるから大丈夫では?」

確かに、最近の現場では HikariCPなどのコネクションプールを使うのが普通だ。

だが重要なのはここだ。

close()は“破棄”ではない。

プール利用時のclose()は、 接続を物理的に切断するのではなく、 プールへ「返却」しているだけだ。

つまり、close()を呼ばなければ、 プールに戻らない。

結果として、

  • 接続が枯渇する
  • 待ちが発生する
  • 最悪、システム停止

try-with-resourcesは、 プール利用環境でも極めて重要なのだ。


■ 実務では自分で書かない?

正直に言うと、 DB接続処理などは共通部品化されていることが多い。

だから普段は、自分でcloseを書くことは少ない。

だが――

「ちょっとした検証コード」
「一時的なバッチ」
「ローカルでのテスト」

こういうときに、自分で書く。

そして、うっかりcloseを書き忘れる。

私はある。


■ Java7で何が変わったのか


try (FileInputStream fis = new FileInputStream("test.txt")) {
    // 処理
} catch (IOException e) {
    e.printStackTrace();
}

tryの丸括弧の中に「resource」を書く。

すると、ブロック終了時に自動でclose()が呼ばれる。

finallyは不要。

ネストも不要。


■ 名前の意味

try-with-resources。

直訳すれば、

「リソース付きtry文」。

リソース(=closeが必要なもの)を tryと一緒に宣言する。

だから、try with resources。


■ AutoCloseableとは何か

対象となるのは、 AutoCloseable を実装しているクラスだ。

つまり「close()メソッドを持つ型」。

  • ファイル(FileInputStream / BufferedReader など)
  • データベース(Connection / Statement / ResultSet)
  • ソケット(Socket)
  • ZipFile
  • Scanner

JDK標準ライブラリの多くはAutoCloseableに対応している。

「closeが必要なものは大体いける」と思ってよい。

さらに、自作クラスでも実装できる。


class MyResource implements AutoCloseable {
    public void close() {
        System.out.println("closed");
    }
}

これは単なる糖衣構文ではない。

リソース管理の統一ルールを作った機能なのだ。


■ Java6方式と混在しても動くのか?

結論から言えば、動く。

だが、保守性は確実に落ちる。

  • 書き方が統一されない
  • レビュー時の負担が増える
  • ミスの温床になる

可能であれば段階的に置き換えるべきだ。

もちろん、 予算と時間が許せば。

だが新規コードでは、必ず使う。


■ まとめ

派手さはない。

ラムダのような衝撃もない。

だが、

try-with-resourcesは、 「書きやすくした機能」ではない。

事故を減らすための設計思想だ。

Javaは派手に変わることもある。
だが、本当に現場を救うのは、
こういう地味な進化かもしれない。





0 件のコメント:

コメントを投稿

【Java進化史 第4回】switch文と設計思想 ― 分岐の向こう側にあるもの

【Java進化史 第4回】switch文と設計思想 ― 分岐の向こう側にあるもの そういえば、最近あまりswitch文を書いていない。 書けなくなったわけではない。 むしろ、書こうと思えばすぐ書ける。 だが設計を考え始めると、 どこかで立ち止まる自分がいる。 ...