Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaのARM(自動リソース管理)とは?try-with-resourcesの基本と使い方を解説

Javaにおける「リソース」とは、AutoCloseableインターフェースを実装したオブジェクトのことを指します。プログラム内でファイルやストリームなどのリソースを使用した場合、使用後には必ずクローズ(解放)することが推奨されています。

従来、このリソースの解放処理はfinallyブロックを使って行うのが一般的でした。まずはその伝統的な方法から見ていきましょう。

finallyブロックを使った従来のリソース管理

以下の例では、try-catch-finally構文を用いて、ファイル読み込み後にストリームを明示的にクローズしています。

コード例

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;

public class FinalExample {
    public static void main(String[] args) throws IOException {
        File file = null;
        FileInputStream inputStream = null;
        try {
            file = new File("D:\\source\\sample.txt");
            inputStream = new FileInputStream(file);
            Scanner sc = new Scanner(inputStream);
            while(sc.hasNextLine()) {
                System.out.println(sc.nextLine());
            }
        } catch(IOException ioe) {
            ioe.printStackTrace();
        } finally {
            inputStream.close();
        }
    }
}

実行結果

This is a sample file with sample text

この方法でもリソースは確実に解放されますが、finallyブロックの記述が冗長になりやすく、close()の呼び出し忘れによるリソースリークのリスクも残ります。

ARM(Automatic Resource Management)とは

JavaにおけるARMとは「Automatic Resource Management(自動リソース管理)」の略で、Java 7で導入された機能です。ARMでは、tryブロックの括弧内でリソースを宣言すると、ブロックの終了時に自動的にクローズされる仕組みになっています。

この構文は「try-with-resources文」とも呼ばれます。try-with-resourcesで宣言できるのはリソース(AutoCloseable型のオブジェクト)のみであり、宣言するオブジェクトは必ずjava.lang.AutoCloseableインターフェース(またはそのサブインターフェースであるjava.io.Closeableなど)を実装している必要があります。

try-with-resources文の基本構文

try(ClassName obj = new ClassName()){
    // 処理コード……
}

JSE 7以降では、このtry-with-resources文が利用可能です。tryブロック内で1つ以上のリソースを宣言すると、それらは使用後に自動的にクローズされます(tryブロックの終了時点で解放)。これにより、finallyブロックで明示的にclose()を呼び出す必要がなくなり、コードがシンプルかつ安全になります。

コード例:try-with-resourcesの使用

次のプログラムは、Javaにおけるtry-with-resourcesの基本的な使い方を示したものです。

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;

public class FinalExample {
    public static void main(String[] args) throws IOException {
        try(FileInputStream inputStream = new FileInputStream(new File("D:\\source\\sample.txt"));) {
            Scanner sc = new Scanner(inputStream);
            while(sc.hasNextLine()) {
                System.out.println(sc.nextLine());
            }
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

実行結果

This is a sample file with sample text

ご覧のとおり、finallyブロックが不要になり、コードが大幅にすっきりしました。例外が発生した場合でも、tryブロックを抜ける時点でinputStreamは自動的にクローズされます。

複数のリソースを扱う場合

try-with-resourcesでは、複数のリソースを同時に宣言することも可能です。セミコロン(;)で区切って宣言したすべてのリソースは、ブロック終了時にまとめて自動的にクローズされます。クローズされる順序は、宣言した順序の逆になります。

コード例:複数リソースによるファイルコピー

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileCopying {
    public static void main(String[] args) {
        try(FileInputStream inS = new FileInputStream(new File("E:\\Test\\sample.txt"));
            FileOutputStream outS = new FileOutputStream(new File("E:\\Test\\duplicate.txt"))){
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inS.read(buffer)) > 0) {
                outS.write(buffer, 0, length);
            }
            System.out.println("File copied successfully!!");
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

実行結果

File copied successfully!!

まとめ

  • リソースとは、AutoCloseableインターフェースを実装したオブジェクトのこと。
  • 従来はfinallyブロックで明示的にclose()を呼び出してリソースを解放していた。
  • Java 7で導入されたARM(自動リソース管理)=try-with-resources文を使えば、リソースは自動的にクローズされる。
  • 複数のリソースも宣言でき、ブロック終了時に一括で解放される。

try-with-resourcesを活用することで、リソースの解放忘れを防ぎ、より安全で読みやすいコードを書くことができます。Java 7以降の環境では、積極的に活用しましょう。

  1. JavaのStringIndexOutOfBoundsExceptionとは?発生原因と対処法をわかりやすく解説

    StringIndexOutOfBoundsExceptionとはJavaにおいて、文字列(String)は一連の文字を格納するために使用され、オブジェクトとして扱われます。文字列は、java.langパッケージに含まれるStringクラスによって表現されます。文字列の作成方法は主に2つあります。1つは他のオブジェクトと同様にnewキーワードを使用する方法、もう1つはプリミティブ型のようにリテラルを直接代入する方法です。String stringObject = new String(Hello how are you); String stringLiteral = Welcome to T

  2. JavaのArrayIndexOutOfBoundsExceptionとは?発生原因と対処法を解説

    配列とインデックスの基本 配列(Array)とは、同じ型の要素を固定サイズで順番に格納するためのデータ構造(コンテナ/オブジェクト)です。配列のサイズ(長さ)は生成時に決定され、後から変更することはできません。 配列内の各要素の位置は「インデックス(添字)」と呼ばれます。Javaの配列は0始まりのため、最初の要素はインデックス0、2番目の要素はインデックス1、というように順に番号が割り当てられます。 配列の各要素へは、「配列名[インデックス]」という形式の式を使ってアクセスします。 System.out.println(myArray[3]); // 1457 が出力される たとえばサイズ7