36

最終ブロックでストリームを閉じたいのですが、ストリームを閉じるためにブロックに別のブロックIOExceptionをネストする必要があるようです。それは正しい方法ですか?少しぎこちないようです。tryfinally

コードは次のとおりです。

 public void read() {
    try {
        r = new BufferedReader(new InputStreamReader(address.openStream()));
        String inLine;
        while ((inLine = r.readLine()) != null) {
            System.out.println(inLine);
        }
    } catch (IOException readException) {
        readException.printStackTrace();
    } finally {
        try {
            if (r!=null) r.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }


}
4

8 に答える 8

36

また、Java 7を使用している場合は、try-with-resourcesステートメントを使用できます。

try(BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()))) {
    String inLine;
    while ((inLine = r.readLine()) != null) {
        System.out.println(inLine);
    }
} catch(IOException readException) {
    readException.printStackTrace();
}           
于 2011-08-28T23:56:11.460 に答える
27

少しぎこちないようです。

です。少なくともjava7がリソースを試してみると、それが修正されます。

java7より前は、closeStreamそれを飲み込む関数を作成できます:

public void closeStream(Closeable s){
    try{
        if(s!=null)s.close();
    }catch(IOException e){
        //Log or rethrow as unchecked (like RuntimException) ;)
    }
}

または、try...finally を try キャッチ内に配置します。

try{
    BufferedReader r = new BufferedReader(new InputStreamReader(address.openStream()));
    try{

        String inLine;
        while ((inLine = r.readLine()) != null) {
            System.out.println(inLine);
        }
    }finally{
        r.close();
    }
}catch(IOException e){
    e.printStackTrace();
}

これはより冗長で、finally の例外は try の例外を隠しますが、Java 7 で導入されたtry-with-resourcesに意味的に近いです。

于 2011-08-28T23:22:16.050 に答える
23

Java 7では、これを行うことができます...

try (BufferedReader r = new BufferedReader(...)){
     String inLine;
     while ((inLine = r.readLine()) != null) {
          System.out.println(inLine);
     }
} catch(IOException e) {
   //handle exception
}
  • tryブロックで変数を宣言するには、を実装する必要がありますAutoCloseable
  • tryブロックで変数を宣言すると、そのスコープもtryブロックに制限されます。
  • tryブロックで宣言された変数は、tryブロックが終了したときに自動的にclose()呼び出されます。

これは、Trywithresourcesステートメントと呼ばれます。

于 2011-08-28T23:57:15.700 に答える
9

はい、それは不格好で、醜く、紛らわしいです。考えられる解決策の 1 つは、 closeQuietlyメソッドを提供するCommons IOを使用することです。

このページの右側の「関連」列に、実際には重複している質問がいくつかあります。この問題に対処する他の方法について、これらを調べることをお勧めします。

于 2011-08-28T23:21:02.567 に答える
6

Commons IO ライブラリに言及している回答と同様に、Google Guava Librariesには、java.io.Closeable に対する同様のヘルパー メソッドがあります。クラスはcom.google.common.io.Closeablesです。探している関数は、Commons IO と同様に名前が付けられています: closeQuietly()。

または、次のように独自にロールして束を閉じることもできます: Closeables.close(closeable1, closeable2, closeable3, ...) :

import java.io.Closeable;
import java.util.HashMap;
import java.util.Map;

public class Closeables {
  public Map<Closeable, Exception> close(Closeable... closeables) {

  HashMap<Closeable, Exception> exceptions = null;

  for (Closeable closeable : closeables) {
    try {
      if(closeable != null) closeable.close();
    } catch (Exception e) {
        if (exceptions == null) {
          exceptions = new HashMap<Closeable, Exception>();
        }
        exceptions.put(closeable, e);
      }
    }

    return exceptions;
  }
}

また、スローされた例外のマップ、またはスローされなかった場合は null も返します。

于 2011-08-29T01:06:32.517 に答える
2

最終的にあなたのアプローチは正しいです。finally ブロックで呼び出すコードが例外をスローする可能性がある場合は、例外を処理するか、ログに記録してください。finally ブロックからバブルを出さないでください。

catch ブロック内で例外を飲み込んでいますが、これは正しくありません。

ありがとう...

于 2011-08-28T23:34:22.877 に答える
0
public void enumerateBar() throws SQLException {
    Statement statement = null;
    ResultSet resultSet = null;
    Connection connection = getConnection();
    try {
        statement = connection.createStatement();
        resultSet = statement.executeQuery("SELECT * FROM Bar");
        // Use resultSet
    }
    finally {
        try {
            if (resultSet != null)
                resultSet.close();
        }
        finally {
            try {
                if (statement != null)
                    statement.close();
            }
            finally {
                connection.close();
            }
        }
    }
}

private Connection getConnection() {
    return null;
}

ソース。このサンプルは私にとって役に立ちました。

于 2013-03-29T04:51:10.637 に答える