`

关于return和finally的执行时机的一点小问题

阅读更多

国庆几天,闲的蛋疼,于是便找了一些以前学过的东西来敲,随后发现了一个小问题。

由于代码教简单,先现出代码:

package cn.lzj0927_cvte_question;
/**
 * return  的用途:导致当前方法的退出,并返回那个值
 * finally :无论异常是否被抛出,finally子句总能被执行
 */
public class TestTryFinally {

	public static void main(String[] args) {
		System.out.println(test());
	}

	public static int test(){
		int x =99;
		try{
			System.out.println("try"+x);
			return x;
		}
		finally{
			System.out.println("finally"+x);
			x=8;
			System.out.println("finally"+x);
		}
	} 
}

  运行结果如下:

try99

finally99

finally8

99

可以看见,在finally中x的值已被改变,可是输出的竟然是x改变之前的值。

test的执行顺序如下:

若try{}子句中有return,那么执行到return时,先不返回,先执行fianlly子句,再返回值。

仔细分析,可以发现,fianlly中改变的只是x在栈中的值,在返回时,变量指向的值并没有被改变。把test代码稍作修改:

public static int test2(){
		int x =99;
		int y =0;
		try{
			System.out.println("try"+x);
			return x;
		}
		finally{
			System.out.println("finally"+x);
			x=y;
			return x;
		}
	} 

 main中输出的便是y的值:0

可推测,在try中执行到return时,先把要返回的引用存到了某一地方,但未返回,当执行完finally时,便调用引用,返回引用所指向的堆中所存的值。因此,在finally中对基本数据类型变量的值的改变对返回值并没有影响,而对对象引用的改变就会对返回值有所影响。

后来我在finally中也加了一个return,输出的是x改变之后的值。可知finally中的return会覆盖try中的return,也就是说,若finally中有return,将直接返回,不会再执行try中的return。

 

分享到:
评论

相关推荐

    Java finally语句到底是在return之前还是之后执行?

    在讨论`finally`语句的执行时机时,我们需要理解Java的异常处理机制。 Java的异常处理机制由`try-catch-finally`结构组成。`try`块包含可能会抛出异常的代码,`catch`块捕获并处理这些异常,而`finally`块则包含...

    java finally块执行时机全面分析

    `finally`块的执行时机是多方面的,下面我们将深入分析其执行流程。 首先,`finally`块不会被跳过,除非遇到以下两种极端情况: 1. 程序通过`System.exit()`退出。 2. 由于硬件故障或操作系统干预导致进程被终止。 ...

    3谈谈final、finally、finaliz1

    然而,这个机制在实际使用中存在诸多问题,比如执行时机不确定、性能开销、可能导致对象复活等问题。因此,它并不推荐用于资源清理,而是更倾向于使用try-with-resources或其他显式关闭资源的方式。自Java 9开始,...

    八成Java开发者解答不了的问题

    Java异常处理有try-catch-finally语句块,测试开发者是否了解finally块的执行时机,即使在return语句或异常抛出时,finally块也会被执行。理解这一特性对于编写健壮的异常处理代码至关重要。 4. 还可能是一个关于...

    Java面试题

    - 综上所述,当try块中有return语句时,finally块将在return语句之前执行。 **总结**: - `finally`块总是会被执行,即使try块中有return语句。 - `finally`块的执行优先级高于try块中的return语句。 - 如果try块中...

    程序员需要知道

    **解答**: 这两种方法都可以用来在 JSP 页面中包含其他 JSP 页面的内容,但它们在处理和执行时机上有所不同。 - **`<%@include file="xxx.jsp"%>`**: 这种包含方式是在 JSP 编译时进行的,也就是说,被包含的 JSP ...

    银海面试题20060301.doc

    【finally块的执行时机】 在`try {}`中有return语句的情况下,finally块的代码总是会在return之前执行。这意味着,即使try中有return,finally中的代码也会被执行完才会返回结果。 【解决24点问题】 使用1,1,1,1...

    上元思创java程序员笔试题面试题.pdf,这是一份不错的文件

    即使在`try`块中有`return`语句,`finally`块的代码也会在`return`之前执行。所以答案是(A)。 3. `InputStream`接口:`flush()`方法不是`java.io.InputStream`的方法,而是`OutputStream`的方法。所以(B)是正确答案...

    2012-Java面试宝典new版

    `finally`块的执行时机 **问题**: `try{}`里有一个`return`语句,那么紧跟在这个`try`后的`finally{}`里的code会不会被执行,什么时候被执行,在`return`前还是后? **答案**: `finally`块中的代码总会被执行,...

    C#面试问题简单提问

    即使有`return`、`throw`或任何其他控制流操作,`finally`块内的代码也会在程序离开当前作用域之前执行。 `finalize`在C#中也称为`~ClassName()`析构函数,类似于Java中的`finalize()`方法,但其实现机制不同。在...

    Java面试32问 面试常见问题

    这意味着,即使在try或catch块中有return语句,finally块中的代码仍然会执行。这通常用于资源清理等操作,确保程序在任何情况下都能释放资源。 - **finalize**:是Object类的一个方法,由垃圾回收器调用,在对象被...

    Java程序员面试宝典——2012版

    `finally`块的执行时机 `finally`块总是会被执行,无论`try`块中是否发生异常,也无论是否有`return`语句。`finally`块中的代码会在`return`语句执行前执行。 #### 39. 输出结果分析 未给出具体代码,但此类题目...

    spring aop的注解配置中,前置,后置,环绕通知,以及异常通知怎么获得被代理方法的参数

    这些通知在特定的时机执行,提供了灵活的代码逻辑插入点。下面我们将详细探讨如何在这些通知中获取被代理方法的参数。 1. **前置通知(Before Advice)** 前置通知在目标方法执行之前运行,通常用于执行校验、日志...

    二十三种设计模式【PDF版】

    关于本站“设计模式” Java 提供了丰富的 API,同时又有强大的数据库系统作底层支持,那么我们的编程似乎变成了类似积木的简单"拼凑"和调用, 甚至有人提倡"蓝领程序员",这些都是对现代编程技术的不了解所至. 在...

    SpringAOP的源码解析.doc

    3. **通知(Advice)**:增强的具体逻辑,根据执行时机的不同,分为四种类型: - **前置通知(Before)**:在目标方法执行之前执行。 - **后置通知(After)**:在目标方法正常执行完毕之后执行。 - **环绕通知(Around)...

    Java程序员面试题集[借鉴].pdf

    - finalize:是Object类中的一个方法,用于在垃圾回收前进行对象清理,但不推荐依赖此方法进行资源释放,因为其执行时机不确定。 2. Anonymous Inner Class 可以继承其他类并实现接口,但不能有名字,常用于创建...

    2022年程序员面试之九阴真经资料.docx

    可以通过调用 `System.gc()` 或 `Runtime.getRuntime().gc()` 来请求执行垃圾回收,但实际执行时机由 JVM 控制。 #### Strings 创建对象数量 - 当执行 `String s = new String("xyz");` 时,实际上创建了两个对象...

    spring03-7

    2. **后置通知(After Return Advice)**: 后置通知在目标方法成功执行并返回后执行。`@AfterReturning`注解用于标记此类通知。它可用于清理工作,例如关闭数据库连接,或者处理返回结果。 3. **异常通知(After ...

    Java常见面试题集及答案.docx

    - `finalize`:是Object类中的一个方法,用于垃圾收集前的清理工作,但不推荐依赖此方法进行资源释放,因为其执行时机不确定。 2. **Anonymous Inner Class(匿名内部类)能否继承其他类和实现接口?** - 可以,...

Global site tag (gtag.js) - Google Analytics