【问题标题】:Finally block excecutionfinally 块执行
【发布时间】:2021-09-14 06:21:35
【问题描述】:

当调用以下方法时,它会将输出打印为 6,但我希望输出为 5,因为我在 finally 块中重新分配了 n = 5。

有人可以帮我解决这个问题吗?

public static int p() {
    int n = 0;
    try {
        n = 6 ;
        return n;
    } catch (Exception e) {
        return n;
    } finally {
        n = 5;
    }
}

【问题讨论】:

  • 但是你已经返回了 6 个。

标签: java block finally


【解决方案1】:

这可以通过了解代码的执行顺序来轻松回答。在您的场景中,您将始终在到达最后一个块之前返回 n 的值,在您的代码中,您将始终返回 6 的值。你永远不会返回5(最终块)或0(捕获块)。

那你为什么永远得不到0

您永远不会得到0,因为try-catch-final 语句的try 部分中的代码在一百万年内永远不会按照它的编写方式抛出任何异常,因此catch 语句是多余的。

那你为什么永远得不到5

您永远不会得到5,因为执行顺序是return 块中的return 语句首先执行然后最后一个块运行。 try-final 语句是我能想到的唯一语句(很高兴在 cmets 中被证明是错误的)任何代码都在 return 语句执行后执行。

没有理由在你的场景中你会有最后一个块,除非你不相信垃圾收集器正在做它的工作,在这种情况下你会nullifyn属性在这里,那就是它。

您的代码可以很容易地改写如下,因为6 是您的代码将返回的唯一值。

public static int p() {
    return 6;
}

【讨论】:

    【解决方案2】:

    正如luk2302 所述,您已经将值返回为 6。如果您想将值返回为 5,请更改您的方法,如下所示。

    public static int p() {
        int n = 0;
        try {
          n = 6;
        } catch (Exception e) {
          return n;
        } finally {
          n = 5;
        }
        return n;
      }
    

    【讨论】:

    • 在return语句之前只有finally块才会执行对吧?那么n应该初始化为5知道吗?
    • @YallalingKolkur 不,最终在您的代码中的 return 语句之后运行(不在此答案的代码中)
    • @YallalingKolkur n 在您的方法之外不可见。因此,您将返回 6,然后将新值 5 分配给 n。该值不会返回给方法的调用者。
    【解决方案3】:

    这个问题很有趣,我什至很惊讶为什么会这样。当我检查 finally 块时,我得到了如下定义

    "Java finally 块是用于执行重要代码的块,例如关闭连接等。Java finally 块无论是否处理异常都会执行。因此,它包含所有需要打印的必要语句无论是否发生异常。”

    但是我已经编译了你的程序并且看到了编译后的类的样子。它给出了答案

    原始 Java 类

    public class Finally {
    
        public static int p() {
            int n = 0;
            try {
                n = 6 ;
                return n;
            } catch (Exception e) {
                return n;
            } finally {
                n = 5;
            }
        }
    
        public static void main(String[] args) {
    
            int n = p();
            System.out.println("value of n " + n);
    
        }
    }
    

    编译类

    public class Finally {
        public Finally() {
        }
    
        public static int p() {
            byte n = 0;
    
            byte var2;
            try {
                n = 6;
                byte var1 = n;
                return var1;
            } catch (Exception var6) {
                var2 = n;
            } finally {
                boolean var8 = true;
            }
    
            return var2;
        }
    
        public static void main(String[] args) {
            int n = p();
            System.out.println("value of n " + n);
        }
    }
    

    正如您所见,return 语句是如何翻译的,因为我们看不到在 finally 块中分配的值,而是在 try 块中分配的值。

    希望能澄清你的答案。

    【讨论】:

    • 类不需要编译,从java原代码可以看出,返回后重新赋值n不影响返回值。并没有什么令人惊讶的。
    • 为什么这会让您感到惊讶?它了解执行顺序,在这种情况下,return 将始终在最后一个块之前执行。在这种情况下,除非您不相信 n 会被垃圾收集,否则没有理由拥有最终块,此时您将使用它将 n 设置为 null
    猜你喜欢
    • 2021-05-13
    • 2018-10-28
    • 2013-01-15
    • 1970-01-01
    • 2010-09-11
    • 2016-02-04
    • 2020-08-16
    • 2014-01-24
    • 1970-01-01
    相关资源
    最近更新 更多