1. 概要

try-with-resources のサポート— Java 7で導入—は、 try ブロックで使用されるリソースを宣言し、リソースの実行後にリソースが閉じられることを保証します。そのブロック。

宣言されたリソースは、AutoCloseableインターフェースを実装する必要があります。

2. try-with-resourcesを使用する

簡単に言えば、自動クローズするには、リソースをtry内で宣言および初期化する必要があります。

try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
    writer.println("Hello World");
}

3. try catch-finallytry-with-resourcesに置き換えます

新しいtry-with-resources機能を使用する簡単で明白な方法は、従来の冗長なtry-catch-finallyブロックを置き換えることです。

次のコードサンプルを比較してみましょう。

1つ目は、典型的なtry-catch-finallyブロックです。

Scanner scanner = null;
try {
    scanner = new Scanner(new File("test.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

そして、これがtry-with-resourcesを使用した新しい非常に簡潔なソリューションです。

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}

ここで、スキャナークラスをさらに詳しく調べます。

4. try-with-resources複数のリソースを使用

try-with-resources ブロックで複数のリソースをセミコロンで区切ることにより、それらを適切に宣言できます。

try (Scanner scanner = new Scanner(new File("testRead.txt"));
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
    while (scanner.hasNext()) {
	writer.print(scanner.nextLine());
    }
}

5. カスタムリソース AutoCloseable

try-with-resources ブロックによって正しく処理されるカスタムリソースを構築するには、クラスはCloseableまたはAutoCloseableインターフェイスを実装し、[ X206X] close メソッド:

public class MyResource implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("Closed MyResource");
    }
}

6. リソースのクロージングオーダー

最初に定義/取得されたリソースは最後に閉じられます。 この動作の例を見てみましょう。

リソース1:

public class AutoCloseableResourcesFirst implements AutoCloseable {

    public AutoCloseableResourcesFirst() {
        System.out.println("Constructor -> AutoCloseableResources_First");
    }

    public void doSomething() {
        System.out.println("Something -> AutoCloseableResources_First");
    }

    @Override
    public void close() throws Exception {
        System.out.println("Closed AutoCloseableResources_First");
    }
}

リソース2:

public class AutoCloseableResourcesSecond implements AutoCloseable {

    public AutoCloseableResourcesSecond() {
        System.out.println("Constructor -> AutoCloseableResources_Second");
    }

    public void doSomething() {
        System.out.println("Something -> AutoCloseableResources_Second");
    }

    @Override
    public void close() throws Exception {
        System.out.println("Closed AutoCloseableResources_Second");
    }
}

コード:

private void orderOfClosingResources() throws Exception {
    try (AutoCloseableResourcesFirst af = new AutoCloseableResourcesFirst();
        AutoCloseableResourcesSecond as = new AutoCloseableResourcesSecond()) {

        af.doSomething();
        as.doSomething();
    }
}

出力:

コンストラクター->AutoCloseableResources_First
コンストラクター->AutoCloseableResources_Second
何か->AutoCloseableResources_First
何か->AutoCloseableResources_Second
AutoCloseableResources_Secondを閉じました
AutoCloseableResources_Firstを閉じました

7. catchおよびfinally

try-with-resources ブロックは、catchとfinallyブロックを持つことができます。これは、従来のtryブロックと同じように機能します。

8. Java 9 –事実上最終変数

Java 9より前は、try-with-resourcesブロック内でのみ新しい変数を使用できました。

try (Scanner scanner = new Scanner(new File("testRead.txt")); 
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { 
    // omitted
}

上に示したように、これは複数のリソースを宣言するときに特に冗長でした。 Java 9以降、 JEP 213 の一部として、try-with-resourcesブロック内でfinal変数または効果的にfinal変数を使用できるようになりました。

final Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))
try (scanner;writer) { 
    // omitted
}

簡単に言うと、変数が final として明示的にマークされていなくても、最初の割り当て後に変更されない場合、変数は事実上finalです。

上に示したように、スキャナー変数は final で明示的に宣言されているため、try-with-resourcesブロックで使用できます。 ライター変数は明示的にfinalではありませんが、最初の割り当て後に変更されません。 したがって、ライター変数も使用できます。

9. 結論

この記事では、try-with-resourcesの使用方法と、 try catch 、およびfinallyをtry-with-resourcesに置き換える方法について説明しました。

また、 AutoCloseable を使用したカスタムリソースの構築と、リソースが閉じられる順序についても検討しました。

この例の完全なソースコードは、このGitHubプロジェクトで入手できます。