Tre*_*kaz 4 java finally try-catch throwable
举个这样的例子:
public List<CloseableThing> readThings(List<File> files) throws IOException {
ImmutableList.Builder<CloseableThing> things = ImmutableList.builder();
try {
for (File file : files) {
things.add(readThing(file))
}
return things.build();
} catch (Throwable t) {
for (CloseableThing thing : things.build()) {
thing.close();
}
throw t;
}
}
Run Code Online (Sandbox Code Playgroud)
代码审查评论的出现是因为通常有一条规则不会捕获Throwable.进行此类仅故障清理的旧模式是:
public List<CloseableThing> readThings(List<File> files) throws IOException {
ImmutableList.Builder<CloseableThing> things = ImmutableList.builder();
boolean success = false;
try {
for (File file : files) {
things.add(readThing(file))
}
success = true;
return things.build();
} finally {
if (!success) {
for (CloseableThing thing : things.build()) {
thing.close();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我觉得这有点乱,并不完全明白它是否与捕捉Throwable有什么不同.在任何一种情况下,异常都会传播.在任何一种情况下,当可能发生OutOfMemoryError时,正在运行其他代码.
那么终于真的更安全吗?
Throwable是Exception和Error的父类型,因此捕获Throwable意味着捕获异常和错误.Exception是你可以恢复的东西(比如IOException),一个更严重的错误,通常你不能轻易恢复(比如ClassNotFoundError)所以除非你知道你在做什么,否则捕获错误没有多大意义.
抓住Throwable进行清理是否可以?
总之一句话......不.
问题是,如果你捕获并重新抛出Throwable,你必须声明该方法抛出Throwable...这将导致调用该方法的任何问题:
Throwable.Throwable时,将包括尚未处理的所有已检查和未检查的异常.)一旦你开始沿着这条路走下去,它throws Throwable就像疾病一样通过呼叫层次传播......
关闭资源的正确方法是使用finally,或者如果您正在编写Java 7或更高版本,则使用"尝试使用资源",并使您的资源可自动关闭.
(在您的示例中,这有点棘手,但您可以扩展现有List类以创建"可关闭列表"类,其中该close()方法关闭所有列表成员.
确实,对于Java 7及更高版本,您可以放弃将封闭方法声明为仅抛出将被捕获的已检查异常.然而,捕捉Throwable进行清理并不是人们期望看到的.人们希望看到一个finally清理条款.如果你以一种时髦的方式做到这一点,你就会让你的代码更难阅读...而且这不是"好".即使你的方式更简洁也不行.
此外,您的版本将无法使用Java 6及更早版本进行编译.
简而言之,我同意您的代码的审核者.
我唯一同意的是,如果你的版本和finally版本都是"安全的",假设它们是正确实现的.(问题是程序员必须在你的情况下更加努力地认识到它是安全的......因为你编写了非惯用的方法.)
| 归档时间: |
|
| 查看次数: |
5840 次 |
| 最近记录: |