Finallyブロックでストリームを閉じたいのですが、IOException
がスローされるため、閉じるためにtry
ブロックに別のfinally
ブロックをネストする必要があるようですストリーム。それは正しい方法ですか?少しぎこちないようです。
これがコードです:
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();
}
}
}
少しぎこちないようです。
そうです。少なくとも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 ...を最後に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で1つを隠しますが、意味的にはJava 7.で導入された try-with-resources に近いです。
また、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();
}
Java 7ではこれを行うことができます...
_try (BufferedReader r = new BufferedReader(...)){
String inLine;
while ((inLine = r.readLine()) != null) {
System.out.println(inLine);
}
} catch(IOException e) {
//handle exception
}
_
AutoCloseable
を実装する必要があります。close()
が呼び出されます。これは Try with resourcesステートメント と呼ばれます。
はい、それは不格好で醜くて混乱しています。 1つの可能な解決策は、 closeQuietly メソッドを提供する Commons IO を使用することです。
このページの右側の「関連」列には実際に重複している質問がいくつかあります。この問題を処理する他のいくつかの方法について、これらを確認することをお勧めします。
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を返します。
最終的に内のあなたのアプローチは正しいです。 finallyブロックで呼び出すコードが例外をスローする可能性がある場合は、必ず処理するか、ログに記録してください。最終ブロックから気泡が出ないようにしてください。
Catchブロック内で、例外を飲み込んでいます-これは正しくありません。
ありがとう...
コードで最初に気付いたのは、中括弧{}をコードから見た場合、それが抜けていることです。また、r
の値をnull
に初期化する必要があるため、最初にnull値をオブジェクトに渡して、作成した条件がnot null
条件チェックを行い、ストリームを閉じます。
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;
}
ソース 。このサンプルは私にとって役に立ちました。