-2

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

1) read 方法中没有返回语句

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)在读取方法中带有返回语句

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();
    }
}
4

3 回答 3

3

原因在控制 try/finally 块执行的Java 语言规范规则中给出。本质上

  • 如果 try 块抛出异常 E 并且 finally 正常完成,则整体 try/finally 抛出 E
  • 如果 try 块抛出 E 但 finally 没有正常完成,则忽略 E 并且整体 try/finally “突然完成”,原因来自 finally 块

显式return被认为是突然完成而不是正常完成,因此在您的示例 2 中,finally 中的 return 掩盖了 try 引发的被零除异常。

于 2014-08-15T09:44:44.197 回答
1

分支语句(return,goto)不应该在 finally 内部使用,因为执行这样的语句会使在 finally 之前执行的其他指令无效。

Java 语言规范说:如果 try 块的执行由于任何其他原因突然完成 R,则执行 finally 块,然后有一个选择:

  1. 如果 finally 块正常完成,则 try 语句由于原因 R 突然完成。
  2. 如果 finally 块由于原因 S 突然完成,则 try 语句由于原因 S 突然完成(并且原因 R 被丢弃)。

注意- finally 块中的 return 语句将导致 try 或 catch 块中可能引发的任何异常被丢弃。

于 2014-08-15T09:44:12.253 回答
0

在这两种情况下,带有 throw a 的代码java.lang.ArithmeticException,但是returninfinally丢弃异常,而是方法退出而不将异常转发给调用者。

这就是为什么通常不应return-block 中finally使用a的原因之一。

这在Java Language Specification (8), 14.20.2 Execution of try-finallyandtry-catch-finally中有描述:

如果 try 块的执行由于 value 的抛出而突然完成V,那么有一个选择:

...(一些类似的,但在这种情况下,不相关的规则被忽略了

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

    • 如果 finally 块正常完成,则 try 语句由于 value 的抛出而突然完成V

    • 如果 finally 块由于原因突然完成S,那么 try 语句由于原因突然完成S(并且值的抛出V被丢弃并忘记)。

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

于 2014-08-15T09:51:00.847 回答