try...catch...finally语句块
try-catch-finally语句主要是用来处理检查异常,捕获并处理,以及最后必须要执行的finally块。
try-catch-finally语句入门:
1.try-catch-finally语句的一般语法形式为:
try {
// 可能会发生异常的程序代码
} catch (Type1 id1) {
// 捕获并处理try抛出的异常类型Type1
} catch (Type2 id2) {
// 捕获并处理try抛出的异常类型Type2
} finally {
// 无论是否发生异常,都将执行的语句块
}
try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch 块:用于处理try捕获到的异常。
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。
但是,在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。
2. try、catch、finally语句块的执行顺序:
1)当try没有捕获到异常时:try语句块中的语句逐一被执行,程序将跳过catch语句块,执行finally语句块和其后的语句;
2)当try捕获到异常,catch语句块里没有处理此异常的情况:当try语句块里的某条语句出现异常时,而没有处理此异常的catch语句块时,此异常将会抛给JVM处理,finally语句块里的语句还是会被执行,但finally语句块后的语句不会被执行;
3)当try捕获到异常,catch语句块里有处理此异常的情况:在try语句块中是按照顺序来执行的,当执行到某一条语句出现异常时,程序将跳到catch语句块,并与catch语句块逐一匹配,找到与之对应的处理程序,其他的catch语句块将不会被执行,而try语句块中,出现异常之后的语句也不会被执行,catch语句块执行完后,执行finally语句块里的语句,最后执行finally语句块后的语句;
图示try、catch、finally语句块的执行:
此处有知识点:对于有多个catch子句的异常程序而言,应该尽量将捕获底层异常类的catch子句放在前面,同时尽量将捕获相对高层的异常类的catch子句放在后面。否则,捕获底层异常类的catch子句将可能会被屏蔽。
try-catch-finally语句进阶:
结论:
1、不管有木有出现异常,finally块中代码都会执行;
2、当try和catch中有return时,finally仍然会执行;
3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
举例:
情况1:try{} catch(){}finally{} return;
显然程序按顺序执行。
情况2:try{ return; }catch(){} finally{} return;
程序执行try块中return之前的(包括return语句中的表达式运算)代码;
再执行finally块,最后执行try中return;
finally块之后的语句return,因为程序在try中已经return所以不再执行。
情况3:try{ } catch(){return;} finally{} return;
程序先执行try,如果遇到异常执行catch块,
有异常:则执行catch中return之前的(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
最后执行catch块中return. finally之后也就是4处的代码不再执行。
无异常:执行完try再finally再return.
情况4:try{ return; }catch(){} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况5:try{} catch(){return;}finally{return;}
程序执行catch块中return之前(包括return语句中的表达式运算)代码;
再执行finally块,因为finally块中有return所以提前退出。
情况6:try{ return;}catch(){return;} finally{return;}
程序执行try块中return之前(包括return语句中的表达式运算)代码;
有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
则再执行finally块,因为finally块中有return所以提前退出。
无异常:则再执行finally块,因为finally块中有return所以提前退出。
最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
编译器把finally中的return实现为一个warning。
下面是个测试程序:
public class Main {
static int test() {
int x = 1;
try {
x++;
return x;
} finally {
++x;
}
} public static void main(String[] args) {
Main m = new Main();
System.out.println(m.test());
}
}
结果是2。
分析:在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。 在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果, 因此,即使finally中对变量x进行了改变,但是不会影响返回结果。它应该使用栈保存返回值。
原博客:深入理解java异常处理机制
有return的情况下try catch finally的执行顺序(最有说服力的总结)
try...catch...finally语句块的更多相关文章
- try catch finally语句块中存在return语句时的执行情况剖析
2种场景 (1) try中有return,finally中没有return(注意会改变返回值的情形);(2) try中有return,finally中有return; 场景代码分析(idea亲测) 场 ...
- finally语句块
finally语句块是搭配着try语句块出现的,也就说必须有try语句块才会有finally语句块,但是并不是try语句块都会搭配有finally语句块出现,我们常见的更多是try...catch.. ...
- Java中try catch finally语句中含return语句的执行情况总结-编程陷阱
前言:有java编程基础的人对java的异常处理机制都会有一定了解,而且可能感觉使用起来也比较简单,但如果在try catch finally语句块中遇到return语句,开发者可能就会遇到一些逻辑问 ...
- Java 中 try、catch、finally 语句块的执行顺序
假设代码顺序书写如下:try → catch → finally → 其他代码 则: 1.正常执行顺序:try → catch → finally → 其他代码 2.try,catch和finally ...
- 异常依然执行{try..catch语句块..}的后续代码
测试异常依然执行{try..catch语句块..}的后续代码: private static Integer testThrows() throws Exception{ Integer result ...
- Java try catch语句块中try()的括号中代码作用
了解过Mybatis,都知道DefacltSqlSession是线程不安全的.每次执行查询都需要新建一个sqlSession.因此官方给的建议写法如下: Mybatis3 从 SqlSessionFa ...
- 【转】Java中try catch finally语句中含有return语句的执行情况(总结版)
Java中try catch finally语句中含有return语句的执行情况(总结版) 有一点可以肯定,finally块中的内容会先于try中的return语句执行,如果finall语句块中也有r ...
- static{ }语句块详解
static{}(即static块),会在类被加载的时候执行且仅会被执行一次,一般用来初始化静态变量和调用静态方法.举ge例子: public class Test { public static i ...
- 转 java中static{}语句块详解
原文地址:http://blog.csdn.net/lubiaopan/article/details/4802430 感谢原作者! static{}(即static块),会在类被加载的时候执 ...
随机推荐
- Mybatis jpa mini 代码解析
源码地址(git):https://github.com/LittleNewbie/mybatis-jpa 一.Mybatis简介 mybatis中文官方文档:http://www.mybatis.o ...
- Java开源博客My-Blog(SpringBoot+Docker)系列文章
My Blog 1.Docker+SpringBoot+Mybatis+thymeleaf的Java博客系统开源啦 2.My-Blog搭建过程:如何让一个网站从零到可以上线访问 3.将数据的初始化放到 ...
- jquery-ajax实现文件上传异常处理web.multipart.MultipartException
异常如下: org.springframework.web.multipart.MultipartException: The current request is not a multipart r ...
- electron入门代码
Electron 提供了一个实时构建桌面应用的纯 JavaScript 环境.Electron 可以获取到你定义在 package.json 中 main 文件内容,然后执行它.通过这个文件(通常我们 ...
- ubuntu下helloworld内核模块编译
1.hello.c #include<linux/init.h> #include<linux/module.h> MODULE_LICENSE("Dual BSD/ ...
- MongoDB增 删 改 查
增 增加单篇文档 > db.stu.insert({sn:'001', name:'lisi'}) WriteResult({ "nInserted" : 1 }) > ...
- vscode--搭建自动编译sass环境
一,安装插件及使用步骤 1.vscode安装Live Sass Compiler,由于该插件依赖Live Server ,所以会自动安装Live Server 2.点击vscode底部的Watch m ...
- XRD 数据处理:使用 Origin 进行多谱图对比
如果一个实验制备了 4 种不同条件下的样品,并分别测得了它们的 XRD 衍射谱图,那么在数据处理中如何用 Origin 软件得到一张多谱图对比的图呢? 样品间的谱图对比 如果只是谱图样品间对比(以 4 ...
- 新的表格展示利器 Bootstrap Table
1.bootstrap table简介及特征 Bootstrap Table是国人开发的一款基于 Bootstrap 的 jQuery 表格插件,通过简单的设置,就可以拥有强大的单选.多选.排序.分 ...
- echarts3.0使用总结
echarts的使用和例子传送门 1.安装echarts npm install echarts --save 这里配置好了,直接输入 npm install //下载插件 npm start //运 ...