2011-09-15 108 views
4

据我所知,下面的两个例子应该做同样的事情。为什么第一次被认为更好?在try/catch块之后使用finally块vs写入代码

1:

​​

2:

try { 
    riskyMethod(); 
} 
catch(Exception e) { 
    //handle exception 
} 
cleanUp(); 

编辑:这个例子是在Java中,但我不知道有关的概念终于在一般块,如在任何语言中使用的

+0

@Greco:你为什么添加C#标签? –

回答

12

那么,如果“处理异常”部分本身抛出异常本身,则不会发生清理。

更重要的是,你应该差不多从来没有被捕获所有例外。您应该注意到您可以处理的非常特殊的例外情况,并让其他例外发生。在这一点上,如果你想清理仍然发生,你必须必须使用finally块。因为非异常异常(Throwable的其他子类)最终会在第一个版本中进行清理,但不会在第二个版本中进行清理 - 但你一般都不应该抓到Exception

就我个人而言,我发现我写了比try/catch或try/catch/finally块更多的try/finally块。我发现很难,我可以真的处理异常...虽然有时我会捕捉一个异常,只是为了将它转换为我正在处理的抽象级别更适合的一个异常,然后重新抛出。

编辑:作为DJ阿基尔的回答指出,finally语句也如果块完成没有异常,例如执行通过return声明。我忘记这一事实是赞成finally的一个好理由:它促进了一致性。无论块如何退出,这是执行清理的一个一致地点。

另请注意,在C#中,您会习惯性地使用using语句来处理可用资源。 Java 7拥有try-with-resources声明。

+1

“我觉得我真的可以处理一个异常很少见。”多么正确!我的想法完全一样。 – Andreas

+1

+1在你的答案中提及** dj aqeel **。 – 2013-02-27 13:42:03

+0

“你应该几乎永远不会捕捉到所有的异常” - 在UI层上你想向用户输出一个简单的友好信息,表明在他试图完成的过程中出现* something *错误? – BornToCode

0

因为“终于”清楚地表明您正在进行清理。

9

由于finally块中的代码总是执行,即使你在try或catch块中有返回语句,异常或其他控制离开语句......最终总是会在除了关闭机器之外的任何情况下执行在最后阻止之前。 :)

+1

哦,已经忘记了退货声明 - 很好。 –

+1

John Skeet评论我的回答....对我来说是一个大奖... – 2011-09-15 06:44:12

+0

实际上,还有一些其他情况下'finally'不会执行。最明显的是如果调用System.exit(),或者try块中的代码永不终止。 –