所以我有一个try / finally块.我需要在finally块中执行许多方法.但是,这些方法中的每一个都可以抛出异常.有没有办法确保在没有嵌套的finally块的情况下调用(或尝试)所有这些方法?
这就是我现在所做的,这非常难看:
protected void verifyTable() throws IOException {
Configuration configuration = HBaseConfiguration.create();
HTable hTable = null;
try {
hTable = new HTable(configuration,segmentMatchTableName);
//...
//varIoUs business logic here
//...
} finally {
try {
try {
if(hTable!=null) {
hTable.close(); //This can throw an IOException
}
} finally {
try {
generalTableHelper.deleteTable(configuration,segmentMatchTableName); //This can throw an IOException
} finally {
try {
generalTableHelper.deleteTable(configuration,wordMatchTableName); //This can throw an IOException
} finally {
generalTableHelper.deleteTable(configuration,haplotypeTableName); //This can throw an IOException
}
}
}
} finally {
HConnectionManager.deleteConnection(configuration,true); //This can throw an IOException
}
}
}
有更优雅的方式吗?
最佳答案
Java中正确的资源管理的标准(工作)方式(该原则也适用于其他语言)是:
Resource resource = acquire(resource);
try {
use(resource);
} finally {
resource.release();
}
或者在当前版本的Java SE中使用快捷方式(带有一点点聪明):
try (Resource resource = acquire(resource)) {
use(resource);
}
(正如Joe K指出的那样,您可能需要包装资源以使其确认Java语言所依赖的特定接口.)
两个资源,您只需应用两次成语:
Resource resource = acquire(resource);
try {
SubResource sub = resource.acquire();
try {
use(sub);
} finally {
sub.release();
}
} finally {
resource.release();
}
在Java SE 7中:
try (
Resource resource = acquire(resource);
SubResource sub = resource.acquire()
) {
use(resource,sub);
}
新语言功能的真正优势在于,在写出时,资源处理往往不会被破坏.
您可能有更复杂的异常处理.例如,您不希望将低级别异常(例如IOException)抛出到正确的应用程序中 – 您可能希望包装一些RuntimeException子类型.使用Execute Around惯用法(参见this excellent question),可以使用Java的典型冗长来解决这个问题.从Java SE 8开始,语法也会缩短,语义也会随机变化.
with(new ResourceSubAction() { public void use(Resource resource,SubResource sub) {
... use resource,sub ...
}});