Javaのtry-with-resourcesとは?JDBCのConnection・Statement・ResultSetを自動で閉じる書き方

最終更新日

Schoo Java入門 中級 第1回 データベース処理

本記事は、Schooの「Java入門 中級【2026年版】」第1回「エンタープライズアプリケーションとデータベース処理」を学ぶ前後に、JDBCでよく使う try-with-resources の考え方を整理したい方向けの記事です。

JDBCでは、データベースに接続したり、SQLを実行したり、検索結果を読んだりするときに複数の部品を使います。この記事では、それらをなぜ閉じる必要があるのか、そして try-with-resources を使うと何が楽になるのかを整理します。

Schoo コースページ:Java入門 中級【2026年版】

なぜJDBCの部品を閉じる必要があるのか

JDBCのSELECT処理では、主に ConnectionStatementResultSet を使います。これらは普通の変数のように見えますが、データベース接続や検索結果を扱うための状態を持っています。

図解:JDBCで開いた部品はデータベース側ともつながっている
Connection
データベースとの接続
conn.close()
Statement
SQLを実行する部品
stmt.close()
ResultSet
検索結果を読む部品
rs.close()
JDBCの部品は、Javaプログラムの中だけで完結しているわけではありません。データベースとの接続や検索結果を扱う状態も持っています。

ローカル環境で小さなプログラムを1回実行するだけなら、閉じ忘れてもすぐに問題が見えないことがあります。プログラムが終了すると、使っていたものがまとめて片付けられる場合があるためです。

しかし、Webアプリや業務アプリのように動き続けるプログラムでは、データベース処理が何度も実行されます。そのたびに接続や検索結果を閉じないまま残すと、使える接続数を圧迫したり、不要な状態を残したりして、後の処理でエラーや遅さの原因になります。

図解:閉じないまま処理をくり返すと接続が残る
1回だけ実行する練習コード
プログラム終了時にOSや実行環境が片付けることもある
閉じ忘れに気づきにくい
動き続けるアプリ
接続や検索結果を扱う状態が残り続ける
接続できない、処理が重い、エラーになる原因になる
ローカルの練習では見えにくくても、アプリが何度もデータベース処理を行う環境では、閉じ忘れが問題になります。

つまり、close() は形式的なお作法ではなく、「データベース処理で使ったものを、使い終わった時点で確実に片付ける」ための処理です。

finallyで閉じる書き方は長くなりやすい

try-with-resourcesを使わない場合、finally の中で close() を呼び出す書き方になります。

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
    conn = DriverManager.getConnection(url);
    stmt = conn.createStatement();
    rs = stmt.executeQuery(sql);

    while (rs.next()) {
        System.out.println(rs.getString("title"));
    }
} catch (SQLException e) {
    e.printStackTrace();
} finally {
    if (rs != null) {
        rs.close();
    }
    if (stmt != null) {
        stmt.close();
    }
    if (conn != null) {
        conn.close();
    }
}

この書き方でも処理はできますが、閉じるためのコードが増えるため、検索処理そのものが見えにくくなります。

try-with-resourcesは自動で閉じる書き方

try-with-resources は、使い終わった部品を自動で閉じるための書き方です。try の丸括弧の中に、閉じたい部品を作ります。

String url = "jdbc:sqlite:db/music.db";
String sql = "SELECT id, title, artist FROM songs";

try (
    Connection conn = DriverManager.getConnection(url);
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery(sql)
) {
    while (rs.next()) {
        int id = rs.getInt("id");
        String title = rs.getString("title");
        String artist = rs.getString("artist");

        System.out.println(title + " / " + artist);
    }
} catch (SQLException e) {
    e.printStackTrace();
}
図解:finallyで閉じる処理をtryの丸括弧に移せる
finallyで閉じる書き方
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;

try {
    conn = DriverManager.getConnection(url);
    stmt = conn.createStatement();
    rs = stmt.executeQuery(sql);
} finally {
    rs.close();
    stmt.close();
    conn.close();
}
try-with-resources
try (
    Connection conn =
        DriverManager.getConnection(url);
    Statement stmt =
        conn.createStatement();
    ResultSet rs =
        stmt.executeQuery(sql)
) {
    // 検索結果を読む
}
try-with-resourcesでは、tryの丸括弧に書いた部品が処理後に自動で閉じられます。

この書き方では、finallyrs.close()stmt.close()conn.close() を明示的に並べなくても、tryブロックを抜けると自動で閉じられます。

処理の流れを読む

try-with-resourcesは、丸括弧の中で部品を用意し、中括弧の中で本来の処理を書く、という形で読みます。

図解:try-with-resourcesの処理の流れ
1. tryの丸括弧で部品を用意する
ConnectionStatementResultSet を作る
2. tryブロックの中を実行する
while (rs.next()) で検索結果を読む
3. ブロックを抜けると自動で閉じる
正常終了でも、途中で例外が起きても閉じる処理が行われる
try-with-resourcesは、処理本体と後片付けを分けて読みやすくするための書き方です。

初学者のうちは、try (...) の丸括弧を「使う部品を用意する場所」、{ ... } の中を「実際の処理を書く場所」と分けて読むと理解しやすくなります。

閉じる順番は後から作ったものが先

try-with-resourcesでは、丸括弧に書いた部品が自動で閉じられます。このとき、閉じる順番は作った順番とは逆になります。

図解:閉じる順番は後から作ったものが先
作る順番
1. Connection
2. Statement
3. ResultSet
閉じる順番
1. ResultSet
2. Statement
3. Connection
検索結果はStatementから作られ、StatementはConnectionから作られます。そのため、内側で使っていたものから順に閉じるイメージです。
try-with-resourcesでは、丸括弧に書いた順番とは逆順で自動的に閉じられます。

通常はこの順番を自分で書く必要はありません。ただし、ResultSetStatementConnection の関係を理解しておくと、JDBCのコード全体が読みやすくなります。

try-with-resourcesを使える条件

try-with-resourcesに書けるのは、閉じる処理を持っているオブジェクトです。Javaでは、AutoCloseable という仕組みに対応しているものを指定できます。

JDBCの ConnectionStatementResultSet はこの仕組みに対応しているため、try-with-resourcesでよく使われます。

確認問題

次の問題で、try-with-resourcesの考え方を確認してみましょう。

第1問

JDBCで ConnectionStatementResultSet を使い終わったあとに閉じる必要があるのはなぜですか。

第2問

try-with-resourcesでは、閉じたい部品をどこに書きますか。

第3問

次の順番で作った場合、自動で閉じられる順番はどうなりますか。

Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);

確認問題の回答例を見る

まとめ

  • JDBCでは、ConnectionStatementResultSet を使い終わったあとに閉じる必要がある
  • try-with-resources を使うと、tryブロックを抜けたときに自動で閉じられる
  • 閉じる順番は、tryの丸括弧に書いた順番とは逆になる

関連記事

シェアする