`
xidajiancun
  • 浏览: 449363 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过我试验,至少有两种情况下finally语句是不会被执行的:

(1)try语句没有被执行到,如在try语句之前就返回了,这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。

(2)在try块中有System.exit(0);这样的语句,System.exit(0);是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。


当然还有很多人探讨Finally语句的执行与return的关系,颇为让人迷惑,不知道finally语句是在try的return之前执行还是之后执行?我也是一头雾水,我觉得他们的说法都不正确,我觉得应该是:finally语句是在try的return语句执行之后,return返回之前执行。这样的说法有点矛盾,也许是我表述不太清楚,下面我给出自己试验的一些结果和示例进行佐证,有什么问题欢迎大家提出来。


1. finally语句在return语句执行之后return返回之前执行的。

public class FinallyTest1 {

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

	public static int test1() {
		int b = 20;

		try {
			System.out.println("try block");

			return b += 80; 
		}
		catch (Exception e) {

			System.out.println("catch block");
		}
		finally {
			
			System.out.println("finally block");
			
			if (b > 25) {
				System.out.println("b>25, b = " + b);
			}
		}
		
		return b;
	}
	
}

运行结果是:

try block
finally block
b>25, b = 100
100
说明return语句已经执行了再去执行finally语句,不过并没有直接返回,而是等finally语句执行完了再返回结果。

如果觉得这个例子还不足以说明这个情况的话,下面再加个例子加强证明结论:

public class FinallyTest1 {

	public static void main(String[] args) {
		
		System.out.println(test11());
	}
	
	public static String test11() {
        try {
            System.out.println("try block");

           return test12();
      } finally {
           System.out.println("finally block");
       }
  }

  public static String test12() {
       System.out.println("return statement");

       return "after return";
   }
	
}
运行结果为:

try block
return statement
finally block
after return

说明try中的return语句先执行了但并没有立即返回,等到finally执行结束后再

这里大家可能会想:如果finally里也有return语句,那么是不是就直接返回了,try中的return就不能返回了?看下面。


2. finally块中的return语句会覆盖try块中的return返回。

public class FinallyTest2 {

    public static void main(String[] args) {

        System.out.println(test2());
    }

    public static int test2() {
        int b = 20;

        try {
            System.out.println("try block");

            return b += 80;
        } catch (Exception e) {

            System.out.println("catch block");
        } finally {

            System.out.println("finally block");

            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }

            return 200;
        }

        // return b;
    }

}

运行结果是:

try block
finally block
b>25, b = 100
200

这说明finally里的return直接返回了,就不管try中是否还有返回语句,这里还有个小细节需要注意,finally里加上return过后,finally外面的return b就变成不可到达语句了,也就是永远不能被执行到,所以需要注释掉否则编译器报错。

这里大家可能又想:如果finally里没有return语句,但修改了b的值,那么try中return返回的是修改后的值还是原值?看下面。


3. 如果finally语句中没有return语句覆盖返回值,那么原来的返回值就不会因为finally里的修改而改变。

public class FinallyTest3 {

    public static void main(String[] args) {

        System.out.println(test3());
    }

    public static int test3() {
        int b = 20;

        try {
            System.out.println("try block");

            return b += 80;
        } catch (Exception e) {

            System.out.println("catch block");
        } finally {

            System.out.println("finally block");

            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }

            b = 150;
        }

        return 2000;
    }

}

运行结果是:

try block
finally block
b>25, b = 100
100
finally里的b = 150;并没有起到作用,这貌似是前面说的有些矛盾,因为前面说try中的return是在finally执行完了才返回的,这里我的解释是:因为try中的return语句已经执行完了只是还没有返回,但是它的返回值已经确定下来了(这里是100),已经跟b这个变量无关了,不会再根据b的值决定返回什么,所以finally里对b的修改只影响b的值对原来已脱离b影响的返回值没有一点影响。这同时也说明了返回语句是try中的return语句而不是finally外面的return b;这句,不相信的话可以试下,将return b;改为return 294,对原来的结果没有一点影响。

这里大家可能又要想:是不是每次返回的一定是try中的return语句呢?那么finally外的return b不是一点作用没吗?请看下面。


4. try块里的return语句在异常的情况下不会被执行,这样具体返回哪个看情况。

public class FinallyTest4 {

    public static void main(String[] args) {

        System.out.println(test4());
    }

    public static int test4() {
        int b = 20;

        try {
            System.out.println("try block");

            b = b / 0;

            return b += 80;
        } catch (Exception e) {

            b += 15;
            System.out.println("catch block");
        } finally {

            System.out.println("finally block");

            if (b > 25) {
                System.out.println("b>25, b = " + b);
            }

            b += 50;
        }

        return 204;
    }

}
运行结果是:

try block
catch block
finally block
b>25, b = 35
85

这里因为在return之前发生了除0异常,所以try中的return不会被执行到,而是接着执行捕获异常的catch语句和最终的finally语句,此时两者对b的修改都影响了最终的返回值,这时return b;就起到作用了。当然如果你这里将return b改为return 300什么的,最后返回的就是300,这毋庸置疑。

这里大家可能又有疑问:如果catch中有return语句呢?当然只有在异常的情况下才有可能会执行,那么是在finally之前就返回吗?看下面。


5. 当发生异常后,catch中的return执行情况与未发生异常时try中return的执行情况完全一样。

public class FinallyTest5 {

	public static void main(String[] args) {

		System.out.println(test5());
	}

	public static int test5() {
		int b = 20;

		try {
			System.out.println("try block");
			
			b = b /0;

			return b += 80;
		} catch (Exception e) {

			System.out.println("catch block");
			return b += 15;
		} finally {

			System.out.println("finally block");

			if (b > 25) {
				System.out.println("b>25, b = " + b);
			}

			b += 50;
		}

		//return b;
	}

}

运行结果如下:

try block
catch block
finally block
b>25, b = 35
35

说明了发生异常后,catch中的return语句先执行,确定了返回值后再去执行finally块,执行完了catch再返回,finally里对b的改变对返回值无影响,原因同前面一样,也就是说情况与try中的return语句执行完全一样。


最后总结:finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句不能影响try或catch中return已经确定的返回值,若finally里也有return语句则覆盖try或catch中的return语句直接返回。


微信学习公众平台-媛媛推荐
程序媛想事儿
微信号:programer-idea
名称:程序媛想事儿

功能介绍:媛媛的主题包括技术蛋糕(包括IT最新资讯、C/C++/Java等编程语言知识及有关算法探讨等IT资料)、生活指南、轻松一刻三个栏目,每天会推送这三个方面的信息给大家,让猿媛们在学习IT知识的同时能关注生活关注健康,同时还能轻松开怀一笑。同时,大家可以回复关键词定制自己想要的信息,如只看C/C++相关资料、只看Java相关资料、只看生活指南或只想开怀一笑都是可以的,后期会根据需要开设疑难解惑等其它平台,欢迎大家加入学习!!!

作者:Alexia(minmin)

CSDN:http://blog.csdn.net/lanxuezaipiao

博客园:http://www.cnblogs.com/lanxuezaipiao/

本文版权归作者和CSDN共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接

否则保留追究法律责任的权利

分享到:
评论

相关推荐

    Java语言finally语句详解,finally到底是在return之前还是之后执行.zip

    Java语言finally语句详解,finally到底是在return之前还是之后执行.zip

    浅谈Java finally语句到底是在return之前还是之后执行(必看篇)

    下面小编就为大家带来一篇浅谈Java finally语句到底是在return之前还是之后执行(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Java中finally块执行与return关系深度剖析

    Java finally语句到底是在return之前还是之后执行?Java finally执行深度剖析,具体看这篇博文:http://blog.csdn.net/lanxuezaipiao/article/details/16922895,这是里面相关的源码,欢迎大家下载使用。

    java 中finally语句块与return的执行关系

    finally语句块与return的执行关系

    java大厂面经、直击BAT

    ## 二.finally finally 一定会被执行,如果 finally 里有 return 语句,则覆盖 try/catch 里的 return , 比较爱考的是 finally 里没有 return 语句,这时... finally到底是在return之前执行还是return之后执行?

    Blog:充当日常笔记或者个人博客吧

    Nginx配置文件详解Linux 安装JenkinsJAVA 多线程详解java 多线程学习How to create a Hello World with IntelliJ and Aspect JJava各种对象(...,JavaBeans)的区分Java finally语句到底是在return之前还是之后执行...

    关于Java中的try-catch-finally语句和return

    第一:return语句并不是函数的终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂存在栈里面,等待finally执行后再返回)  第二:finally里面不建议放return语句,根据需要,return语句...

    Java异常处理中同时有finally和return语句的执行问题

    主要介绍了Java异常处理中同时有finally和return语句的执行问题,首先确定的是一般finally语句都会被执行...然后,需要的朋友可以参考下

    关于Java中try finally return语句的执行顺序浅析

    主要介绍了关于Java中try finally return语句的执行顺序浅析,需要的朋友可以参考下

    浅谈Java中return和finally的问题

    在Java中当try、finally语句中包含return语句时,执行情况到底是怎样的,finally中的代码是否执行,大家众说纷纭,有的说会执行,有的说不会执行,到底哪种说法正确,下面我们来详细讨论下

    josonle#Coding-Now#finally语句如何执行1

    - 无论try是否发生异常,finally语句都会执行- 如果try/catch中包含控制转移语句(return、continue、break),finally

    JAVA+OOP自测

    2、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的代码会不会被执行,什么时候被执行?B A. 不会执行 B. 会执行,在return前执行 C. 会执行,在return后执行 D. 会执行,可能在return前执行,也...

    try~catch~finally中关于return的问题

    在Java的异常机制中,如果finally中含有return语句,则try和catch中的return语句将会被JVM忽视

    谈谈Java中try-catch-finally中的return语句

    我们知道return语句用在某一个方法中,一是用于返回函数的执行结果,二是用于返回值为void类型的函数中,仅仅是一个return语句(return ;),此时用于结束方法的执行,也即此return后的语句将不会被执行,当然,这种...

    java是去蜗牛还是源码时代-JavaInterviewQuestions:Java面试题

    finally代码是在return之后还是之前执行? throws是获取异常,throw是抛出异常,try是将会发生异常的语句括起来,从而进行异常的处理, catch是如果有异常就会执行他里面的语句,而finally不论是否有异常都会进行...

    Java问题宝典2012版

    38、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后? 27 39、下面的程序代码输出的结果是多少? 28 40、final, finally, finalize的区别。 30 ...

    Java常见面试题208道.docx

    77.try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 78.常见的异常类有哪些? 八、网络 79.http 响应码 301 和 302 代表的是什么?有什么区别? 80.forward 和 redirect 的区别? 81.简述 tcp...

    java面试宝典

    21、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 10 22、我们在web 应用开发过程中经常遇到输出某种编码的字符,如iso8859-1等,...

    java 面试题 总结

    换言之,很可能数个使用者在执行某个 Stateless Session Bean 的 methods 时,会是同一个 Bean 的 Instance 在执行。从内存方面来看, Stateful Session Bean 与 Stateless Session Bean 比较, Stateful Session ...

Global site tag (gtag.js) - Google Analytics