最终吞噬了例外

时间:2011-01-17 07:56:05

标签: java exception

static int retIntExc() throws Exception{
    int result = 1;
    try {
        result = 2;
        throw new IOException("Exception rised.");
    } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println(e.getMessage());
        result = 3;
    } finally {
        return result;
    }
}

我的一位朋友是.NET开发人员,目前正在迁移到Java,他问我关于这个来源的以下问题。从理论上讲,这必须throw IOException("Exception rised."),整个方法retIntExc()必须throws Exception。但没有任何反应,该方法返回2.

我没有测试他的例子,但我认为这不是预期的行为。

编辑:感谢所有答案。你们有些人忽略了这个方法被称为retIntExc的事实,这意味着这只是一些测试/实验的例子,显示了投掷/捕捉机制的问题。我不需要'修复',我需要解释为什么会这样。

7 个答案:

答案 0 :(得分:16)

这就是你无法从C#中的finally块返回的原因:)

这绝对是Java语言规范中规定的行为。它在section 14.20.2中指定。

  

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

回归是突然完成的一个例子;如果finally块引发异常,突然完成,丢失原始异常。

上面的引用来自这套嵌套的项目符号,省略了不适用的选项:

  
      
  • 如果由于抛出值V而突然完成try块的执行,则可以选择:      
        
    • 如果V的运行时类型不能分配给try语句的任何catch子句的参数,则执行finally块。然后有一个选择:      
          
      • 如果finally块因为S而突然完成,那么try语句突然完成原因S(并且丢弃并抛弃值V的抛出)。
      •   
    •   
  •   

答案 1 :(得分:3)

它将返回2,因为

finally始终执行

答案 2 :(得分:2)

无论抛出什么异常,finally块都会执行。在您声明的catch块捕获异常后,它不会立即执行。它在try之后执行,并且如果有任何则捕获异常。如果您的方法抛出异常,除非您在方法中吞下它并返回result,否则它不会返回任何内容。但你不能兼得。

此外,除非您的方法有任何其他代码,否则永远不会遇到ArrayIndexOutOfBoundsException

答案 3 :(得分:2)

这是因为您在异常传递之前发出了一个return语句,因此返回了一个有效值。你不能同时返回一个值并抛出异常。

删除返回周围的finally块将提供您想要的行为。

答案 4 :(得分:0)

IOException 类不是 ArrayIndexOutOfBoundsException 类的子类,因此将永远不会执行catch部分。

如果更改为此,则返回3.

static int retIntExc() throws Exception{
        int result = 1;
        try {
            result = 2;
            throw new ArrayIndexOutOfBoundsException ("Exception rised.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println(e.getMessage());
            result = 3;
        } finally {
            return result;
        }
    }

答案 5 :(得分:0)

我不明白为什么这不会是预期的行为。到此代码块结束时,结果等于2.

static int retIntExc() throws Exception{
        int result = 1;
        try {
            result = 2;

然后抛出一个异常,但是你的catch块会捕获不同类型的异常,因此不执行任何操作。

        throw new IOException("Exception rised.");
    } catch (ArrayIndexOutOfBoundsException e) {
          ...
    }

保证finally块被执行,所以最后一步是返回2.

这次成功的回报否决了冒泡异常。如果您希望异常继续冒泡,那么您不能返回finally块。

答案 6 :(得分:0)

通过将return放在finally方法中,您可以覆盖抛出的异常,而是返回结果。你的代码应该是这样的:

static int retIntExc() throws Exception{
        int result = 1;
        try {
            result = 2;
            throw new IOException("Exception rised.");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println(e.getMessage());
            result = 3;
        } finally {
            // do something
        }
        // it gets here only when exception is not thrown
        return result;
    }