Javaの try-with-resources文の紹介

# 導入
今回はJava7以降で使用可能な`try-with-resources`文について紹介していきます。
これは以前のこちらの記事で触れた「入出力ストリーム」における課題を解決するのに向いているので、ぜひ参考にしてください。

https://qiita.com/F-monsoon/items/cac08dc5475c8f4ee69e

# try-with-resources文の紹介

プログラムでファイルやネットワーク接続、データベースなどを利用する際、リソースの管理は非常に重要です。特に、リソースを使い終わった後の「クローズ処理」を忘れると、メモリリークや他の問題の原因になります。

従来の方法では、`finally`句で手動でリソースを閉じる必要がありましたが、Java 7から導入された`try-with-resources`文を使えば、リソースの自動解放が可能になります。これにより、コードが簡潔になり、クローズ処理の記述漏れを防ぐことができます。

## 1. 従来のtry-finallyによるリソース管理

従来のリソース管理では、次のように`try-finally`を使います。

```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class SampleIO {
    public static void main(String[] args) {
        String str = "";
        System.out.println("「;;」と入力し、Enterを押して入力終了");
        BufferedReader br = null;

        try {
            // ストリームの生成
            br = new BufferedReader(new InputStreamReader(System.in));
            while (!str.equals(";;")) {
                System.out.println("入力: ");
                str = br.readLine();
                // 入力値のコンソール出力
                System.out.println("入力値: " + str);
            }
        } catch (IOException e) {
            // 例外処理
            e.printStackTrace();
        } finally {
            // ストリームのクローズ
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
```

このコードの問題点は、**クローズ処理の冗長さ**です。クローズ処理を手動で記述する必要があり、忘れやすく、バグの原因になりがちです。

## 2. try-with-resourcesによる簡潔なリソース管理

Java 7以降、`try-with-resources`文を使えば、リソースのクローズ処理を自動化できます。次の例では、`try-with-resources`を使ってリソース管理を簡潔にしています。

```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class SampleIO {

    public static void main(String[] args) {
        String str = "";
        System.out.println("「;;」と入力し、Enterを押して入力終了");

        // tryのあとの()の中でストリーム生成
        try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {

            while (!str.equals(";;")) {
                System.out.println("入力: ");
                str = br.readLine();
                // 入力値のコンソール出力
                System.out.println("入力値: " + str);
            }
        } catch (IOException e) {
            // 例外処理
            e.printStackTrace();
        }
    }
}
```

**try-finally**と比べて、`try-with-resources`は`finally`句を省略し、リソースの生成を`try`の`()`内に記述するだけで、リソースが自動的にクローズされます。これにより、**コードがすっきりし、バグのリスクを減らす**ことができます。

## 3. Java 9以降の書き方

Java 9以降では、次のように`try`の前でリソースを生成し、そのオブジェクトを`try`の`()`内で管理することもできます。

```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class SampleIO2 {

    public static void main(String[] args) {
        String str = "";
        System.out.println("「;;」と入力し、Enterを押して入力終了");

        // tryの前でストリーム生成
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        // tryの()内にストリームを設定
        try (br) {
            while (!str.equals(";;")) {
                System.out.println("入力: ");
                str = br.readLine();
                // 入力値のコンソール出力
                System.out.println("入力値: " + str);
            }
        } catch (IOException e) {
            // 例外処理
            e.printStackTrace();
        }
    }
}
```

`try`の前でリソースを生成し、それを`()`内で管理することで、さらに柔軟なコード記述が可能です。

## 最後に

`try-with-resources`文の最大のメリットは、**自動的にリソースを解放**してくれる点です。これにより、クローズ処理を忘れる心配がなくなり、**コードの可読性と保守性**が大幅に向上します。特に複雑なリソース管理が必要なプログラムでは、この機能を積極的に活用することをお勧めします。