这道面试题,出错率 90%
关注“Java 后端技术全栈”
回复“面试”获取全套面试资料
大多数公司针对初级、中级都会有笔试的这个环节,甚至很多高级面试也存在笔试环节。对于笔试大家千万不要掉以轻心,笔试题做不好,很有可能面试就黄了或者随便找个面试官应付一下就可以回去等通知了。
今天我们分享的这个面试题,出现的频率是相当高。
案例
我们先上代码:
`public class TryFinallyDemo {
public static void main(String[] args) {
TryFinallyDemo tryFinallyDemo = new TryFinallyDemo();
System.out.println(tryFinallyDemo.test());
}
public String test() {
String name = "苍老师";
try {
return name;
} finally {
name = "小泽";
}
}
}
`
运行上面这段代码,输出什么?
是"苍老师"还是"小泽"?
其实,对于 java 开发者来说,finally 已经是老熟人了。
有时候,程序在 try 块里打开了一些物力资源(比如:数据库连接,网络连接、磁盘文件等),这些物力资源都是必须要我们手动回收。
那就该它出场了---finally。
一个完整的 java 异常处理结构如下:
`public void test(){
try{
//业务代码
}catch(SubException e1){
//异常处理模块 1
}catch(SubException e2){
//异常处理模块 1
}finally{
//资源回收模块
}
}
`
为了保证一定能回收 try 模块中打开的物力资源,一场极致提供了 finally 模块。不管 try 模块中的代码是否异常,也不管是哪一个 catch 被执行,甚至 try 或者 catch 模块中执行了 return 语句,finally 模块总会被执行。
try、catch、finally 三者的组合关系为:
在前面已经提到了,不管 try 里是否有异常,不管 try 或者 catch 是否有 return 语句,finally 里的代码块会执行。
如果在 try 模块没有发生异常,那么代码正常执行完毕,在执行 finally 模块。
如果 try 模块发生异常并且被 catch 模块捕获了,那么在 catch 模块内的代码执行结束后再执行 finally 模块。
如果 try 模块中有异常并且没有 catch 模块或者没有被 catch 模块捕获到,那么在异常被跑出去之前执行 finally 模块。
异常相关推荐这篇文章:
于是乎,很多人就认为答案是:小泽
运行代码,输出的居然是:苍老师
是不是很懵逼?为什么是“苍老师”?
不着急,下面我们来好好分析分析。
我们先通过 javac 编译,再通过 javap 命令查看看字节码内容。内容如下:
整个过程
第一步:将"苍老师"放入操作栈中,然后将操作数栈中的数据保存在本地变量 1 中,将本地变量 1 放入操作数栈中,然后将操作数栈中的数据保存在本地变量 2 中。
第二步:将“小泽”放入操作栈中,然后将操作数栈中的数据保存到本地变量 1 中。
第三步:将本地变量 2 放入操作数栈中,将操作数栈中的数据返回。
所以上面的面试题,最终返回的是苍老师。
另外,如果在 try 模块出现异常,那么也是在 finally 模块执行完了再向外面抛出异常的。
`public String test() {
String name = "苍老师";
try {
int a = 1/0;
return name;
} finally {
System.out.println("finally");
name = "小泽";
}
}
`
调用这个方法必然会出现异常:
从输出日志中可以看出,异常时在 finally 模块后执行。
例外
如果我们在 try 模块代码中有下面这行代码,finally 模块就不会执行了。
`System.exit(0);
`
总结
本文讲述了 finally 如何使用。以及哪些情况下 finally 模块会执行,哪些情况下不会被执行,finally 模块和 try 模块的关系。希望大家不管是在工作中还是面试都能轻松应对。
没有学不好的技术,只有不爱学习的人~
推荐阅读
版权声明: 本文为 InfoQ 作者【田维常】的原创文章。
原文链接:【http://xie.infoq.cn/article/fd81920f16591d67ae675a6f3】。文章转载请联系作者。
评论