我发现自己经常编写 API 来提供由网络连接支持的 Iterator<Foo>
。该实现打开网络连接,从流中读取信息,并将该信息反序列化为 Foo
以传递给调用者。不幸的是,总是有可能出现 IOException
并且需要优雅地关闭网络连接(当调用者读取最后一个 Foo
时可以自动完成,但如果没有发生呢?)。
已经有几个问题( here 和 here )关于如何处理将在 Iterator
的实现中抛出的已检查异常,并且接受的建议是“将它们包装在未检查的 RuntimeException
中”。同时为了允许关闭网络连接,我们可以实现 Closeable
。所以对于一个行为良好的异常检查调用者,我们最终得到了这样的结果:
Iterator<Foo> iter = null;
try {
iter = getFooIterator();
while(iter.hasNext()) {
Foo foo = iter.next();
// do something with foo
}
}
catch(RuntimeException e) {
if(e.getCause() instanceof IOException) {
// do something with the IOException
}
else throw e;
}
finally {
if(iter instanceof Closeable) try { ((Closeable)iter).close(); } catch(IOException e) {}
}
实现
Iterator
似乎是个好主意。有没有更好的办法? 最佳答案
IMO 的第一步是将其包装在特定于实现或应用程序的异常中,从而无需捕获通用 RuntimeException
或检查根本原因。
我会考虑一个特定的实现来避免可关闭检查并结束 IOException
。
NetworkIterator<Foo> iter = null;
try {
iter = getFooIterator();
while (iter.hasNext()) {
Foo foo = iter.next();
// do something with foo
}
} catch (NetworkIteratorExceptiom e) {
// do something with the IOException
} finally {
iter.close();
}
我可能不会给出让样板消失的方法,但我很想;大致:
NetworkIterator<Foo> iter = new IteratorThang<Foo>() {
@Override public void each(Foo foo) {
// Do something with foo
}
};