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 政策阻止” [重复]