我在上一篇中总结了java中finally结构的3个典型问题,以及展示了finally结构可能产生的副作用。在这一篇中,我将继续展示finally的一些特点。
如果try块中有导致try块提前退出的语句(如return语句和throw语句,我们以return语句为例),那么finally会在return语句之前先执行。
比如有如下函数:
public static int testVariableChangeInFinally()
{
int i=0;
try{
i=1;//步骤1
return i;//步骤2
}finally{
i=2;//步骤3
}
}
那么,函数真正的执行顺序应该是
步骤1->步骤3->步骤2。然而执行该函数时,函数的返回值却是1。why?这导致我们有2个新的假设:
1,执行顺序不是我们想的那样;
2,步骤3根本就没执行;
第2个假设是很好排除的,我们在步骤3下面再加入一条输出语句,形成代码如下
/**
*
* @return
*/
public static int testVariableChangeInFinally()
{
int i=0;
try{
i=1;
return i;
}finally{
i=2;
System.out.println("finally");
}
}
运行函数,发现控制台确实打印出了finally字符串,说明步骤3确实是被执行过了。说明假设2不成立。(如果是怀疑是乱排序了,那么可以用eclipse一步一步调试)
难道执行顺序不是步骤1->步骤3->步骤2吗?答案是只对了1半。
实际上,在虚拟机内部,return语句是分为2步的,第一步是把返回值压入到调用者的栈中,第二步是返回到调用者的栈。因此,我们可以把我们的代码想象成如下形式:
/**
*
* @return
*/
public static int testVariableChangeInFinally() {
int i = 0;
try {
i = 1;//步骤1
int temp = i;//步骤2
return temp;//步骤3
} finally {
i = 2;//步骤4
}
}
因此,执行顺序应该是
步骤1->步骤2->步骤4->步骤3。
所以,函数也就返回了1,而不是2。我们也可以通过eclipse的单步调试观察i值的变化,发现i也确实变成了2。
分享到:
相关推荐
在本文中,我们将深入探讨 `finally` 的使用和一些需要注意的细节,尤其是与Java相关的知识点。 首先,`finally` 通常与 `try-catch` 结构一起使用。在 `try` 块中,我们执行可能会抛出异常的代码。如果发生异常,...
下面将详细介绍try-catch-finally语句的使用方法和注意事项。 一、try块 try块是try-catch-finally语句的核心部分,用于包装可能出现异常的代码。try块中的代码在执行时,如果出现异常,会被catch块捕获和处理。...
在 try-catch-finally 结构中,finally 语句块的执行顺序是非常重要的。下面我们来详细探讨 finally 语句块与 return 的执行关系。 首先,需要了解的是,在 try-finally 或者 catch-finally 中,如果 try 或者 ...
在编程语言中,`try-finally` 结构是用来确保一段代码在任何情况下(无论是正常执行还是抛出异常)都会被执行的语句块。这个结构在处理资源管理,比如文件流关闭或者网络连接断开等场景时特别有用。当我们谈论`...
重要的是要注意,`finalize()` 不应该被用作清理逻辑的唯一手段,因为垃圾回收机制的工作时间和顺序是不确定的。通常,我们应该依赖于更可靠的机制,如上述的 `finally` 块或 `try-with-resources`。 总结,`final...
但要注意,`finally`块中的`return`语句会覆盖掉`try`或`catch`中的`return`结果。 3. 示例代码: ```java try { // 可能会抛出异常的代码 File file = new File("example.txt"); FileReader fr = new ...
当`finally`块抛出异常时,以下几点值得注意: 1. **异常覆盖**:如果`finally`块中抛出了新的异常,那么原本在`try`块中抛出的异常会被新异常所覆盖。这意味着原始异常的信息将会丢失,除非在`finally`块内部捕获...
使用finally块需要注意以下几点: 1. finally块只能用在try/catch语句中。 2. finally块中的代码一定会被执行,除非程序中止或退出。 3. finally块可以用于释放资源,例如关闭数据库连接、文件流等。 4. finally块...
在使用多异常捕获应注意两点:(1)多种异常之间用竖线(|)分隔,(2)捕获多种类型的异常时,在catch块中可以使用instanceof关键字来检测异常的类型。 在Java中,try…catch…finally语句块是异常处理的主要形式...
**注意**:`finally`块可以不与`catch`块一起使用,但是必须与`try`块一起使用。 #### finally关键字的典型应用场景 `finally`关键字最常见的应用场景之一是在需要释放资源的情况下。例如,在与数据库交互的过程中...
需要注意的是,虽然`finally`块总会执行,但并不是所有情况都适用。如果`try`或`catch`块中包含`System.exit()`这样的代码,它会导致程序立即终止,`finally`块将不会被执行。此外,如果在多线程环境下,线程被中断...
try catch finally组合的语法结构如下: ```java try { // 可能会抛出异常的语句 } catch (异常类型 e) { // 异常处理语句 } finally { // 资源释放语句 } ``` 多个catch组合: 多个catch组合用于捕获多种类型...
【英语二小作文结构与常用句型解析】 在准备考研英语的过程中,小作文部分占据了十分重要的地位,其分值为10分,虽然篇幅较短,但要求内容精炼、结构清晰。小作文通常涉及多种类型,如感谢信、祝贺信、道歉信、邀请...
总结一下,使用`try-catch-finally`时需要注意以下几点: 1. `try`块用于包围可能抛出异常的代码。 2. `catch`块捕获`try`块中抛出的异常,可以有多个`catch`块处理不同类型的异常。 3. `finally`块中的代码无论如何...
在Java编程语言中,`try-catch-finally`语句块是异常处理的关键构造,它允许程序员优雅地处理可能出现的异常情况。...在实际编程中,要注意`finally`块可能会影响方法的返回值,这在设计复杂的控制流程时需要特别注意。
异常处理是Java中不可或缺的一部分,通过try-catch-finally结构捕获并处理运行时可能出现的错误。良好的异常处理可以使程序更健壮,提高用户体验。 再者,Java标准库提供了丰富的API,如集合框架(List、Set、Map等...
但需要注意的是,`finally` 块中的 `return` 语句会覆盖掉 `try` 或 `catch` 块中的 `return` 语句,因此在处理返回值时要格外小心。例如: ```java public class Test { public static void main(String[] args)...
- 在第二个示例中,`j`的值为2,`i / j`操作不会抛出异常,因此直接跳过`catch`块,执行`finally`块,输出2。 5. 异常层次结构: C#的异常类继承自`System.Exception`,你可以创建自定义异常类来表示特定类型的...
异常处理机制用于捕获和处理程序运行过程中可能出现的错误,通过try-catch-finally结构实现。 - **1.3.8 C#的标准输入/输出流** C#提供了丰富的标准输入输出流,如Console类,用于控制台应用程序的输入输出。 - *...