在java中,如果try和catch都抛出相同的exception并最终返回该怎么办?
public class Abc { public static void main(String args[]) { System.out.println(Abc.method()); } static int method() { try { throw new Exception(); } catch(Exception e) { throw new Exception(); } finally { return 4; } } }
为什么返回值为4?
这就是finally
工作方式。 片段
try { throw new Exception(); } catch(Exception e) { throw new Exception(); }
将突然完成,但finally子句将启动,当它返回时,它会丢弃完成声明的原始原因。
这在Java语言规范中的块和语句一节中进行了解释。 我已经在你的情况中突出了相关的路径:
通过首先执行
try
块来执行具有finally
块的try
语句。 然后有一个选择:
- 如果
try
块的执行正常完成,则执行finally
块,然后有一个选择:
- …
- 如果
try
块的执行由于throw
值V而突然完成,那么有一个选择:
- 如果V的运行时类型可分配给
try
语句的任何catch
子句的参数,则选择第一个(最左边)这样的catch
子句。 将值V分配给所选catch
子句的参数,并执行该catch
子句的Block 。 然后有一个选择:
- 如果
catch
块正常完成,则执行finally
块。 然后有一个选择:
- …
- 如果
catch
块由于原因R突然完成,则执行finally
块。 然后有一个选择:
- 如果
finally
块正常完成,那么try
语句突然完成,原因是R。- 如果
finally
块因为原因S而突然完成,则try
语句突然完成,原因是S (并且原因R被丢弃)。- 如果V的运行时类型不能分配给
try
语句的任何catch
子句的参数,则执行finally
块。 然后有一个选择:
- …
- 如果
try
块的执行由于任何其他原因R突然完成,则执行finally
块。 然后有一个选择:
- …
你永远不应该从finally块返回。 这是非常糟糕的做法。 请参阅Java try-finally返回设计问题并最终总是在Java中执行? 。
有关StakOverflow的几个问题可以解释这一点。
为简单起见:如果在finally子句中放入return或throw语句,则这是方法的最后一个操作。 一般来说,这是一种不好的做法。
最后将始终返回4. finally块将始终执行,无论try和catch块中是否存在任何exception。
finally块返回一个值的事实导致吞下抛出的exception,因此它不会传播出该方法。