Developer

【はじめてのJava】try-with-resources文【例外処理編】
2021.09.30
Lv1

【はじめてのJava】try-with-resources文【例外処理編】

はじめてのJava

このシリーズでは、初めてJavaやプログラミングを勉強する方向けに、Javaによるプログラミングの基礎を説明していきます。
目標レベルは、Javaの資格試験の一つである「Oracle Certified Java Programmer, Silver」(通称Java Silver)に合格できる程度の知識の習得です。
はじめてJavaやプログラムに触れる方にもできるだけわかりやすい解説を心がけていきます。


例外の対応

前回の記事では、複数の例外をキャッチする方法を紹介しました。
今回は、Java7のバージョン以降で追加された特殊な例外処理の書き方を紹介していきます。

目次


特殊な例外処理の記述

例外処理の方法として、例外に対応する方法をいくつか紹介してきましたが、Java7というバージョン以降では、少し特殊な記述で例外処理を行うことができるようになりました。
その記述法を紹介する前に、例外処理が必要になる場合について思い出してみましょう。
プログラムの中で利用する際に、例外処理が必須な例外クラスがありました。入出力関連のクラスやデータベース関連のクラスが代表的な例です。
また、これらのクラスを利用する際には、利用し終わった後に必ず「リソースの解放」を行う必要があります。
まずは、「リソースの解放」について説明していきます。


リソースの解放とは

Javaのプログラムの中で外部との接続を行うとき、必ずその対象と接続して、様々な処理をするためのオブジェクトを利用します。
処理が終了したら、そのオブジェクト(接続)を閉じ(解放)なければならないとされています。
理由としては、ファイルの場合には、あるプログラムが接続したままでは、他のプログラムが同じファイルを開くことが出来ないということが起こったり、データベースでは、接続を閉じないままにしてしまうと、接続できる上限数に達してしまって、あるタイミングから接続ができなくなるといったエラーにつながるためです。

接続を閉じる(解放する)ときには「close()」メソッドというメソッドを利用します。
closeメソッドはプログラムの処理が通常終了した場合でも、異常終了した場合でも必ず行わなければなりません。
一般的には、closeメソッドはfinallyブロックの中で実行します。


try-with-resources文

リソースの解放を行う際に、finallyブロックの中でcloseメソッドを記述する方法が一般的ですが、それではコードが非常に長くなってしまうという欠点があります。
そこで、より短くリソースの解放を記述するためにJava7から「try-with-resources文」という記述方法が追加されました。
「try-with-resources文」では、tryブロックの中で利用したオブジェクトをtryブロックが終了した時に自動的にcloseするという処理を行ってくれます。
これによって、明示的にfinallyブロックの中でcloseメソッドを書かなくても、リソースの解放が行われるようになります。
構文は以下のようになります。
[構文]

try( 例外処理が必要なオブジェクトの作成 ){
	オブジェクトを利用して処理を行う
}catch( 例外クラス 変数 ){
	例外が起きた時の処理
}

実際にfinallyブロックを利用したプログラムの記述とtry-with-resources文を利用したプログラムの記述を比べてみましょう。
・finallyブロックでの書き方

public class Sample {
    public static void main(String[] args) {
        FileWriter fw = null;
        try {
            fw = new FileWriter("/sample.txt");
            fw.write("sample");
        }catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fw != null) {
                try{ //closeメソッドでも「IOException」が発生する可能性があるので、さらにtyr-catchで囲む!
                    fw.close();
                }catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

・try-with-resources文での書き方

public class Sample {
    public static void main(String[] args) {
        try(FileWriter fw = new FileWriter("/sample.txt");) {
            fw.write("sample");
        }catch (IOException e) {
        	e.printStackTrace();
        }
    }
}

Closable・AutoClosableインターフェース

「try-with-resources文」はどのような場合でも利用できるわけではありません。
ここで自動的にcloseすることができるクラスは「AutoCloseableインターフェースというインターフェースを実装しているクラス」のみです。
また、Javaには「Closableインターフェース」というインターフェースも用意されており、ClosableインターフェースはAutoClosableインターフェースを継承しているため、Closableインターフェースを実装したクラスも「try-with-resources文」を利用することができます。

public class Sample {
    public static void main(String[] args) {
        try (TryWithResourcesSample tr = new TryWithResourcesSample();) {
        //独自に作成したクラスでも、AutoCloseableインターフェースを実装したクラスなので、try-with-resources文で利用可能!
        } catch (Exception e) {

        }
    }
}

class TryWithResourcesSample implements AutoCloseable {
    //AutoCloseableインターフェースを実装したクラスを作成する
    @Override
    public void close() throws Exception {

    }
}

例外処理編・次回の内容

今回はtry-with-resources文を利用した例外処理の方法を紹介しました。
次回は、例外を逃れる(別のクラスに任せる)方法を解説していきます。


初めてのJavaシリーズの目次はこちら
例外処理編の記事一覧はこちら


java 11 の練習問題一覧はこちら
はじめてのJavaシリーズの練習問題一覧はこちら