本篇博客主要为大家整理了关于java中面向对象中异常处理try-catch-finally格式中关于finally的一些常见的面试问题知识点的解析,是对这块内容的知识的一个汇总。
1.finally是什么?
首先了解一下finally是什么?finally是异常处理try-catch-finally格式中必然执行的异常统一处理出口,无论是否发生异常,finally都必然执行。
2.finally不执行的情况
在面试的时候我们经常会被问到,当什么什么情况出现后,finally还会不会执行?注意了,只有当出现程序结束,内存没了的情况,比如说停电了、电脑关机了等等这种情况下,还有
一种是执行了程序退出指令代码退出了JVM的情况下,只有这两种情况出现了,finally才会没有执行,否则finally必然执行。
3.finally执行的时机
面试的时候我们可能会被问到如下这个问题:
我们上面说过,除了出现那两种情况,否则finally必然执行。上面这个问题的答案涉及finally的执行时机:出现异常进入catch了,它会执行完先计算返回值并将返回值存储起来等待返回,
然后执行finally代码块的内容,最后再将之前存储的返回值返回出去。finally是执行在return之前,即使没有出现异常,不走catch代码块,在try中return了,finally也还是会执行。
接下来这两块内容就是面试中的最经常被难倒的地方了!
4.引用数据类型中使用finally的案例剖析(难点1)
我们来看一段代码:
在try中person p 的属性age等于18,然后在finally中将age改为了28,最后在main方法执行后打印的对象p的age最终结果为28。
这段代码在内存中运行的过程是这样的:
首先main方法创建了一个person对象p,它在堆内存中开辟了一块空间存储它的age属性,在栈内存中它存储的是堆内存的引用地址,我们假设这个地址为0x123。接着程序走到try代码块
将这块0x123堆内存地址中的age赋值为了18,并将该堆内存地址进行了备份作为返回值存储起来准备return。然后程序走到finally中的代码块将对象p的age改为了28,它就是找到堆内存地址上的这块空间改了里面的这个属性age,将它改为了28。最后return了,它因为return的返回值备份的是这个堆内存指向地址0x123,去找这里面的age的值,而这时候的值已经被改为了28。所以最后程序走完打印的这个返回值就是28。
这是这种引用数据类型中使用finally的案例解析,下面要讲的非引用数据类型案例与这块内容刚好做一个比较。
5.非引用数据类型中使用finally的案例剖析(难点2)
我们再来看这段代码:
在静态类haha中我们定义了一个变量a=10,然后代码执行到try中要准备一个返回值return,因为代码不会出错,就没有进catch,继续走到finally将变量a改为了20。那最终程序走完main方法中打印的这个返回值为什么还是10呢?这个与上面的案例怎么不一样了呢?
其实这个案例与上面的案例的不同点在与它是属于非引用对象的数据类型。
这个案例的代码在内存中的运行过程是这样的:
它首先是在栈内存中存储变量a=10,然后进入try代码块中将a的值为10存储起来准备return。接着因为代码不会出错就没进入catch走到finally,finally代码块将变量a的值改为了20。但是因为之前备份的就是int a=10这个数据,而不是备份的堆内存地址指向,所以最终打印的返回值a的值还是10。
这块就是非引用对象数据的案例的解析,与上面的案例做了一个比较分析。
到这里就是我们面试中常见的异常处理中关于finally的一些面试中经常被问到的知识点的总结,对于以后我们面试可以少走一些坑,有收获记得点赞关注我哦!谢谢大家!