尝试和最后给出没有return语句的异常,但是当在方法中写入return语句时没有异常

时间:2014-08-15 09:31:07

标签: java return try-finally

请解释为什么Exception出现在第一个程序中而不是出现在第二个程序中。

1)在read方法中没有return语句

class Example
{   
    public static void read()
    {
        try
        {
             int i = 9/0;
        }
        finally
        {
              System.out.println("This proogram is giving exception");
        }       
    }

    public static void main(String[] fel)
    {
         read();
    }
}

2)在read方法中使用return语句

class Example
{   
    public static void read()
    {
         try
         {
               int i = 9/0;
         }
        finally
        {
               System.out.println("This proogram is not giving exception");
               return;
        }       
    }

    public static void main(String[] fel)
    {
          read();
    }
}

3 个答案:

答案 0 :(得分:3)

原因在管理try / finally块执行的Java Language Specification规则中给出。基本上

  • 如果try块抛出异常E并且finally正常完成则整个try / finally抛出E
  • 如果try块抛出E但是finally not 正常完成,则忽略E并且整体try / finally"突然完成"由于最终阻止而产生的原因

显式return被认为是突然而不是正常完成,所以在你的例子2中,finally中的返回掩盖了try引发的被零除异常。

答案 1 :(得分:1)

最终不应在内部使用分支语句(return,goto),因为执行此类语句会使最终执行之前执行的其他指令无效。

Java Language Specification说:如果由于任何其他原因导致try块的执行突然完成,则执行finally块,然后有一个选择:

  1. 如果finally块正常完成,则try语句突然完成,原因是R。
  2. 如果finally块因为S而突然完成,则try语句突然完成,原因为S(并且原因R被丢弃)。
  3. 注意 - finally块内的return语句将导致丢弃try或catch块中可能抛出的任何异常。

答案 2 :(得分:0)

在这两个实例中,抛出java.lang.ArithmeticException的代码,但return中的finally会丢弃异常,而是退出方法而不将异常转发给调用者。

这就是为什么你应该return - 块中使用finally的原因之一。

Java Language Specification (8), 14.20.2 Execution of try-finally and try-catch-finally

中对此进行了描述
  

如果由于抛出而导致try块的执行突然完成   值V,然后有一个选择:

     

...(一些类似的但是对于这种情况,不相关的规则被遗漏了

     
      
  • 如果V的运行时类型与try语句的任何catch子句的可捕获异常类不兼容,则执行finally块。然后有一个选择:

         
        
    • 如果finally块正常完成,那么try语句会因为抛出值V而突然完成。

    •   
    • 如果finally块突然因原因S而完成,则try语句突然完成,原因为S(并且丢弃了值V的抛出并且忘了)。

    •   
  •   

您可以在JLS 14.1 Normal and Abrupt Completion of Statements中找到突然和正常完成的定义。但基本上return被视为突然完成。