java:尝试最终阻止执行[重复]

Posted

技术标签:

【中文标题】java:尝试最终阻止执行[重复]【英文标题】:java: try finally blocks execution [duplicate] 【发布时间】:2013-08-10 11:39:48 【问题描述】:

当 try 块中存在 return; 时,我对 try-finally 的执行感到困惑。在我的理解中,finally 块总是会被执行,即在返回调用方法之前。在考虑以下简单代码时:

public class TryCatchTest 
    public static void main(String[] args)
        System.out.println(test());
    
    static int test()
        int x = 1;
        try
            return x;
        
        finally
            x = x + 1;
        
    

打印出来的结果实际上是1。这是否意味着finally块没有被执行?谁能帮帮我?

【问题讨论】:

为什么不在 finally 块中添加System.out.println() 看看自己呢?我认为它已执行但返回的值为 1。 使用 try catch 时,可以“捕捉”特定类型的异常(例如:IOException、NullPointerException 等)。finally 语句在特定异常发生时发生,您需要在此之前运行一些代码无论如何都要抓住...... Here's 点赞时需要考虑的事情 @RicardoE - 不完全正确。如果输入了 try 区域,finally 子句(缺少一些混乱的递归异常情况)总是执行。 @Keyser 因为像 Rohit 这样的人的回答,他们花时间实际解释正在发生的事情和所有底层功能,以便每个人,不仅仅是提问者,都可以提出更多全面了解。 【参考方案1】:

当您从try 块返回时,返回值存储在该方法的堆栈帧中。之后执行 finally 块。

更改 finally 块中的值不会更改堆栈中已经存在的值。但是如果从 finally 块中再次返回,堆栈上的返回值将被覆盖,并返回新的x

如果你在 finally 块中打印x 的值,你就会知道它被执行了,并且x 的值会被打印出来。

static int test()
    int x = 1;
    try
        return x;
    
    finally
        x = x + 1;
        System.out.println(x);  // Prints new value of x
    


注意:如果返回引用值,则引用值存储在堆栈中。在这种情况下,您可以使用该引用更改对象的值。

StringBuilder builder = new StringBuilder("");
try 
    builder.append("Rohit ");
    return builder;

 finally 
    // Here you are changing the object pointed to by the reference
    builder.append("Jain");  // Return value will be `Rohit Jain`

    // However this will not nullify the return value. 
    // The value returned will still be `Rohit Jain`
    builder =  null;

建议阅读:

JVM Specs - Frames

【讨论】:

补充:只有返回的value本身存储在堆栈中。如果您要返回对对象的引用,则在 finally 块中对对象字段所做的修改仍然可见。 @JasonC。没错。将添加到答案。谢谢:) 如果有人对为什么builder = null 不使返回值无效,那是因为pass by value 的事情。 @Keyser。没错。【参考方案2】:

finally 块被执行。局部变量递增。但是该局部变量的值已经被复制为返回值。

来自 Java 语言规范,14.17: The return statement:

带有表达式的 return 语句尝试将控制权转移给调用者 包含它的方法;表达式的值变为 方法调用。

...

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

【讨论】:

好吧,我想有人必须真正阅读文档。每个派对都有一个便便。【参考方案3】:

您在退出尝试之前返回 x。我会这样做:

public class TryCatchTest 
    public static void main(String[] args) 
        System.out.println(test());
    
    static int test() 
        int x = 1;
        try 
            do something with x.
         finally 
            do something that will happen even in case of error;
            x = x + 1;
            return x;
        
    

【讨论】:

我认为这没有抓住重点。

以上是关于java:尝试最终阻止执行[重复]的主要内容,如果未能解决你的问题,请参考以下文章

尝试/最终阻止与调用处置?

当我尝试使用 Axios 调用 Instagram API 时,我“被 CORS 政策阻止” [重复]

阻止在极短的时间重复执行某个函数

Java volatile 是不是会阻止缓存或强制执行直写缓存?

阻止执行到下一行,直到来自 Api 的响应 [重复]

PEP8 不允许尝试除阻止 [重复]