在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块的执行由于throwV而突然完成,那么有一个选择:
    • 如果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,因此它不会传播出该方法。