【问题标题】:try/finally without catch with return statement? [duplicate]尝试/最终不使用返回语句捕获? [复制]
【发布时间】:2016-04-15 22:35:56
【问题描述】:

为什么下面代码的结果是 3,为什么即使编译器首先检查 try,finally get 也会终止并退出方法,为什么 try 中的 return 不会终止方法?

public int returnVal(){ 
    try{
        return 2;
    }
    finally{
        return 3;
    }
}

【问题讨论】:

  • finally 块总是在最后被调用,这就是为什么它被称为“finally”(想想“试试这个,捕获任何异常,最后做那个”)。
  • finally总是无论如何都会执行..
  • 是的,我理解,但是为什么编译器会忽略 try 中的 return 语句,即使它在运行时进入它,为什么 try 中的 return 不会终止方法
  • finally 块总是被执行除非您执行System.exit() 或JVM 崩溃。

标签: java exception return try-catch


【解决方案1】:

JLS 14.17

可以看出,return 语句总是突然完成。

前面的描述说“尝试转移控制”,而不仅仅是“转移控制”,因为如果方法或构造函数中有任何 try 语句(第 14.20 节),其 try 块或 catch 子句包含 return 语句,那么任何 finally这些 try 语句的子句将按从内到外的顺序执行,然后将控制权转移到方法或构造函数的调用者。 finally 子句的突然完成可能会中断由 return 语句启动的控制转移。

特别检查短语attempts to transfer control 和最后一句。 try return 尝试转移控制权,最后是disrupt the transfer of control initiated by a return statement

换句话说,try attempts to transfer the controll,但是由于 finally 块的执行仍然是开放的,并且包含一个返回语句,因此在 finally 块中尝试的控制转移具有更高的 preceding。这就是为什么您会看到在 finally 块中返回的值 3

【讨论】:

    【解决方案2】:

    finally 在从try(或catch)返回值之前执行。

    如果在finally 中存在return 语句,它将覆盖try(或catch)块的返回。

    所以在这种情况下,finally 的返回也会获胜:

    try {
        // Exception thrown
        return 2;
    } catch (Exception e) {
        return 1;
    } finally {
        return -1;   // Always returns -1 also if a return statement is present in the try and in the catch clause
    }
    

    【讨论】:

    • +1,因为它比最佳答案更容易理解(当然,以更少的信息为代价)。
    【解决方案3】:

    为什么 try 中的 return 不会终止方法?

    Is it bad practice to return from within a try catch finally block?

    您必须注意,当您将返回值放入 try-catch 语句时,返回值本身由异常处理块保存和管理。

    异常块仅存储您的退货,并且仅在完成所有验证后才真正返回,这并不意味着 finally 块真的会对您的退货产生影响:

    public int returnVal() { 
        int i = 0;
        try {
            return i;
        }
        finally {
            i = 99;
        }
    }
    

    在这种情况下,返回仍然是 0。

    但是在您在问题中提到的情况下,您会第二次影响返回,并且由于异常块不想让您的返回继续,直到它完成所有验证,您只是总是存储一个在您的异常块中返回值 2 次。结果将始终为 3。

    请记住,如果您将 return 放入 try-catch-finally 中,则该 return 将在 finaly 块运行之前不会返回;退货本身只是被存储,直到一切都得到验证。

    【讨论】:

      【解决方案4】:

      finally explication 当你写一个 finnaly 块时,这些总是执行它。

      【讨论】:

        【解决方案5】:

        finally 块总是在控制权返回给调用函数之前执行。 所以在这种情况下,在返回 2 之前,它会调用 finally 并返回 3。

        【讨论】:

          猜你喜欢
          • 2016-01-10
          • 2010-09-21
          • 1970-01-01
          • 1970-01-01
          • 2014-11-05
          • 2013-11-17
          • 1970-01-01
          • 1970-01-01
          • 2016-05-02
          相关资源
          最近更新 更多