88

例外がスローされた場合、バッファリングされたリーダーとファイルリーダーが閉じられ、リソースが解放されることを期待しています。

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
    {
        return read(br);
    } 
}

catchただし、成功した閉鎖のための条項を設ける要件はありますか?

編集:

基本的に、Java 7 の上記のコードは、Java 6 の以下のコードと同等です。

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{

    BufferedReader br = null;

    try
    {
        br = new BufferedReader(new FileReader(filePath));

        return read(br);
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        try
        {
            if (br != null) br.close();
        }
        catch(Exception ex)
        {
        }
    }

    return null;
}
4

2 に答える 2

105

それは正しく、catch句の要件はありません。Oracle Java 7 doc は、例外が実際にスローされるかどうかに関係なく、リソースが閉じられると述べています。

catch例外に対応したい場合にのみ句を使用してください。このcatch句は、リソースが閉じられた後に実行されます。

Oracle のチュートリアルの抜粋を次に示します。

次の例では、ファイルから最初の行を読み取ります。BufferedReader のインスタンスを使用して、ファイルからデータを読み取ります。BufferedReader は、プログラムが終了した後に閉じる必要があるリソースです。

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
} // In this example, the resource declared in the try-with-resources statement is a BufferedReader.

... BufferedReader インスタンスは try-with-resource ステートメントで宣言されているため、try ステートメントが正常に完了したか突然完了したかに関係なく (メソッド BufferedReader.readLine が IOException をスローした結果として) 閉じられます。

編集

新しい編集された質問について:

Java 6 のコードは、ブロックを実行しcatch、その後finallyブロックを実行します。これにより、リソースがcatchブロック内で開かれたままになる可能性があります。

Java 7 構文では、リソースはブロックのに閉じられるため、リソースはブロックの実行catch中に既に閉じられています。catchこれは、上記のリンクに記載されています。

try-with-resources ステートメントでは、宣言されたリソースが閉じられた後に、catch または finally ブロックが実行されます。

于 2013-07-15T09:40:04.470 に答える
69

この特定のケースでは、try-with-resources の使用は問題なく機能しますが、一般的には正確ではありません。不快な驚きにつながる可能性があるため、そのようにリソースをチェーンしないでください。可変バッファー サイズがあるとします。

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (BufferedReader br = new BufferedReader(new FileReader(filePath), sz))
    {
        return read(br);
    } 
}

何かがうまくいかず、szネガティブになってしまったとします。この場合、( で作成されたnew FileReader(filePath))ファイル リソースは閉じられません。

この問題を回避するには、次のように各リソースを個別に指定する必要があります。

public static Object[] fromFile(String filePath) throws FileNotFoundException, IOException
{
    int sz = /* get buffer size somehow */
    try (FileReader file = new FileReader(filePath);
         BufferedReader br = new BufferedReader(file, sz))
    {
        return read(br);
    } 
}

この場合、初期化がbr失敗しfileても閉じられます。詳細については、こちらこちらをご覧ください。

于 2014-01-25T09:37:02.290 に答える