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