最后用返回和它返回的值来理解try-catch



我有以下一段代码。

public static void main(String[] args) {
    System.out.println(returnString());
}
private static String returnString(){
    try {
        System.out.println("Executing try");
        return "Return try value";
    } catch (Exception e){
        System.out.println("Executing Catch");
        return "Return catch value";
    } finally {
        System.out.println("Executing finally");
        return "Return finally value";
    }
}

其输出为

Executing try
Executing finally
Return finally value

如果我将我的finally块更改为不返回任何类似的内容

public static void main(String[] args) {
    System.out.println(returnString());
}
private static String returnString(){
    try {
        System.out.println("Executing try");
        return "Return try value";
    } catch (Exception e){
        System.out.println("Executing Catch");
        return "Return catch value";
    } finally {
        System.out.println("Executing finally");
    }
}

然后输出为

Executing try
Executing finally
Return try value

现在我明白了finally总是被执行的,除非我们调用system.exit(0);调用或JVM崩溃。我不明白的是,为什么返回值发生了变化?我仍然希望它返回try块的值
有人能解释为什么要考虑finally值而不是try块的返回值吗?

请不要回答,因为即使try块中有返回,finally也会执行。。。或者只有当存在系统时才最终不执行。exit(0);调用或JVM崩溃。正如我所知

编辑:

(根据Dirk对此的评论)
public static void main(String[] args) {
    System.out.println(returnString());
}
private static String returnString(){
    try {
        System.out.println("Executing try");
        return printString("Return try value");
    } catch (Exception e){
        System.out.println("Executing Catch");
        return printString("Return catch value");
    } finally {
        System.out.println("Executing finally");
        return printString("Return finally value");
    }
}
private static String printString(String str){
    System.out.println(str);
    return str;
}

输出:

Executing try
Return try value
Executing finally
Return finally value
Return finally value

就在从主块返回之前,JVM必须确保finally块已执行,因此它会执行此操作。其思想是执行finally块,然后返回并从主块执行return语句。但是,如果在finally块中有一个return语句,那么它将在执行finally块时执行。。。这意味着控制永远不会返回到主块以完成CCD_ 7语句。

  1. JVM在主块中遇到return语句。它暂停主块的执行并检查finally子句
  2. 它完整地执行finally子句,包括它的return语句
  3. 因此,它从未完成try

然而,请注意,try块的return表达式被求值,然后被丢弃。如果它有副作用,这一点很重要。因此,如果你的主块有return i++,那么这对返回值没有影响,但i仍然会增加。(感谢Dirk指出这一点。)

如果您最终返回,那就是最终返回

这并不奇怪。这是实际行为。返回在finally块中决定的值。

如果您在finally中没有返回任何内容,则返回值的前一个值就是返回值(在您的情况下,是try块值)。

不管你在try中做什么,finally块总是执行,即使你从try块返回(如果你最终返回,那就是最终返回)。

来自finally文档

运行时系统始终执行finally块中的语句,而不管在try块中发生了什么。所以这是进行清理的最佳场所。

注:最后设计为清理。

在Java中,代码:

try {
  if (foo()) return 1;
} catch (Exception e){
  if (goo()) return 2;
} finally {
  if (moo()) return 3;
}

将由编译器重写为:

try {
  if (foo())
  {
    if (moo()) return 3;  // Finally code executed before return
    return 1;
  }
} catch (Exception e){
  if (goo())
  {
    if (moo()) return 3;  // Finally code executed before return
    return 2;
  }
} catch (Throwable e){
  if (moo()) return 3;   // Finally code executed before re-throw
  throw e;
}
if (moo()) return 3;    // Finally code executed before leaving block

基本上,编译器将在每个执行路径中复制finally块中的代码一次,这将导致代码执行离开保护块,无论是通过returnthrow还是失败。请注意,虽然某些语言不允许在finally块内使用return,但Java不允许;但是,如果由于异常而执行了finally块,则该块中的return可能会导致异常被静默放弃(请参阅上面标记为"重新抛出前最后执行的代码"的代码;如果执行return 3;,则会跳过重新抛出)。

相关内容

  • 没有找到相关文章

最新更新