私はこの小さな静的ユーティリティクラスを使用します。原則として、処理を誤って(何か)冗長に実行する必要がある場合、または最終的にブロックする場合は、アプリケーションコードを散らかすのではなく、少なくとも1回はリッピングして実装します。手元のタスクから気を散らすもの:
package krc.utilz.io;
import java.io.Closeable;
import krc.utilz.reflectionz.Invoker;
public abstract class Clozer
{
/**
* close these "streams"
* @param Closeable... "streams" to close.
*/
public static void close(Closeable... streams) {
Exception x = null;
for(Closeable stream : streams) {
if(stream==null) continue;
try {
stream.close();
} catch (Exception e) {
if(x!=null)x.printStackTrace();
x = e;
}
}
if(x!=null) throw new RuntimeIOException(x.getMessage(), x);
}
/**
* Close all the given objects, regardless of any errors.
* <ul>
* <li>If a given object exposes a close method then it will be called.
* <li>If a given object does NOT expose a close method then a warning is
* printed to stderr, and that object is otherwise ignored.
* <li>If any invocation of object.close() throws an IOException then
* <ul>
* <li>we immediately printStackTrace
* <li>we continue to close all given objects
* <li>then at the end we throw an unchecked RuntimeIOException
* </ul>
* </ul>
* @param Object... objects to close.
*/
public static void close(Object... objects) {
Exception x = null;
for(Object object : objects) {
if(object==null) continue;
try {
Invoker.invoke(object, "close", new Object[]{} );
} catch (NoSuchMethodException eaten) {
// do nothing
} catch (Exception e) {
e.printStackTrace();
x = e;
}
}
if(x!=null) throw new RuntimeIOException(x.getMessage(), x);
}
}
try{stream1.close();}catch{} try{stream2.close();}catch{}
一般的なコップアウトとは異なり、最後のクローズ例外が存在する場合でもスローされることに注意してください。
乾杯。キース。