• 正常执行流程
try执行,遇到异常就跳到catch执行(以使得程序不会崩溃);
不管有没有异常catch,最后都执行finally
 
  • 含return语句执行流程分析
若try块中return 可达, return语句(如:return x=x+1;)
  1. 对x执行运算x=x+1 (若有运算)
  2. 复制一个变量x给try的return语句(按值复制:基本类型就是值本身,对象就是地址值)
  3. 但return语句并不马上返回,控制权转移到finally块中执行: (1)若finally中无return语句:finally执行完后,try块执行return语句返回之前复制的变量x(基本类型就是值本身,对象就是地址值)(所以:若x为基本类型,fianlly中改变x对最终return结果无效;若x为对象类型,按地址值传递可以改变x的最终return结果)    (2)若finally中有return语句:执行后直接返回(即“覆盖try中return语句”:try中return语句不再返回)
 
若try中return 不可达(exception 在return前出现
    exception出现后控制权直接转到catch 块(即try中 exception之后的语句<包括return>不会执行),最后到finally块(catch到finally中流程与上面try到finally中流程相同)
 
 
  • finally不执行的特殊情况
  1. if you call System.exit() or
  2. if the JVM crashes first
 
  • A return statement in the finally block is a bad idea
By doing a return from the finally block, you suppress the exception entirely.(finally 中有return ,try,catch的 return throw都不会再被调用)
  1. publicstaticint getANumber(){
  2.     try{
  3.         thrownewNoSuchFieldException();
  4.     } finally {
  5.         return43;
  6.     }
  7. }
Running the method above will return a “43” and the exception in the try block will not be thrown. This is why it is considered to be a very bad idea to have a return statement inside the finally block.
 
 

例子解释:
 
执行流程
  1. If the return in the try block is reached, it transfers control to the finally block, and the function eventually returns normally (not a throw).
  2. If an exception occurs, but then the code reaches a return from the catch block, control is transferred to the finally block and the function eventually returns normally (not a throw).
  3. In your example, you have a return in the finally, and so regardless of what happens, the function will return 34, because finally has the final (if you will) word.
 
 
finally语句在try或catch中的return语句执行之后、return返回之前执行的

  • 在try中含有return+基本类型情况:
  1. publicclassFinallyTest1{
  2.     publicstaticvoid main(String[] args){
  3.         System.out.println(test1());
  4.     }
  5.     publicstaticint test1(){
  6.         int b =20;
  7.         try{
  8.             System.out.println("try block");
  9.             return b +=80;
  10.         }
  11.         catch(Exception e){
  12.             System.out.println("catch block");
  13.         }
  14.         finally {
  15.             System.out.println("finally block");
  16.             if(b >25){
  17.                 System.out.println("b>25, b = "+ b);
  18.             }
  19.         }
  20.         return b;
  21.     }
  22. }
运行结果:
  1. try block
  2. finally block
  3. b>25, b =100
  4. 100
 
  • 在catch中含有return+基本类型情况(分析跟在try中含有return情况一样):
  1. publicclassTest{
  2.  
  3.     publicstaticvoid main(String[] args){
  4.  
  5.         System.out.println(test1());
  6.     }
  7.  
  8.     publicstaticint test1(){
  9.         int b =20;
  10.  
  11.         try{
  12.             int a =1/0;//触发异常
  13.             System.out.println("try block");//不会被执行
  14.             return b +=80;//不会被执行
  15.         }
  16.         catch(Exception e){
  17.             System.out.println("catch block");
  18.             return b +=180;//最后在此返回
  19.         }
  20.         finally {
  21.             System.out.println("finally block");
  22.             if(b >25){
  23.                 System.out.println("b>25, b = "+ b);
  24.             }
  25.         }
  26. //        return b;
  27.     }
  28.  
  29. }
执行结果:
  1. catch block
  2. finally block
  3. b>25, b =200
  4. 200
 
  • 在try中含有return+对象类型情况:
  1. publicclassTest{
  2.  
  3.     publicstaticvoid main(String[] args){
  4.         System.out.println(getMap().get("KEY").toString());
  5.     }
  6.  
  7.     publicstaticMap<String,String> getMap(){
  8.         Map<String,String>map=newHashMap<String,String>();
  9.         map.put("KEY","INIT");
  10.  
  11.         try{
  12.             map.put("KEY","TRY");
  13.             returnmap;//return在控制权转移到finally前:复制了一个map对象的地址值(对象按地址值传递)
  14.         }
  15.         catch(Exception e){
  16.             map.put("KEY","CATCH");
  17.         }
  18.         finally {
  19.             map.put("KEY","FINALLY");//根据对象地址值修改对象内容(按地址值传递),因此会影响try中return返回的对象内容
  20.             map= null;//map为null即不再指向该对象,
  21.             // 但由于前面return复制了一个对象的引用(地址值),而对象是被分配在堆中的,只要有引用指向这个对象,系统就不会回收此对象, 所以此处map = null 并不会影响最后try中return返回对象内容
  22.         }
  23.  
  24.         returnmap;
  25.     }
  26.  
  27. }
执行结果:
  1. FINALLY

  • 在catch中含有return+基本类型情况(分析跟在try中含有return情况一样):
  1. publicclassTest{
  2.  
  3.     publicstaticvoid main(String[] args){
  4.         System.out.println(getMap().get("KEY").toString());
  5.     }
  6.  
  7.     publicstaticMap<String,String> getMap(){
  8.         Map<String,String>map=newHashMap<String,String>();
  9.         map.put("KEY","INIT");
  10.  
  11.         try{
  12.             int a =1/0;//触发异常
  13.             map.put("KEY","TRY");//不会被执行
  14.             returnmap;//不会被执行
  15.         }
  16.         catch(Exception e){
  17.             map.put("KEY","CATCH");
  18.             returnmap;//return在控制权转移到finally前:复制了一个map对象的地址值(对象按地址值传递)
  19.         }
  20.         finally {
  21.             map.put("KEY","FINALLY");//根据对象地址值修改对象内容(按地址值传递),因此会影响catch中return返回的对象内容
  22.             map= null;//map为null即不再指向该对象,
  23.             // 但由于前面return复制了一个对象的引用(地址值),而对象是被分配在堆中的,只要有引用指向这个对象,系统就不会回收此对象,
  24.             // 所以此处map = null 并不会影响最后catch中return返回对象内容
  25.         }
  26.  
  27. //        return map;
  28.     }
  29.  
  30. }
执行结果:
  1. FINALLY
 
 
finally块中的return语句会覆盖try块中的return返回
  1. publicclassTest{
  2.  
  3.     publicstaticvoid main(String[] args){
  4.  
  5.         System.out.println(test2());
  6.     }
  7.  
  8.     publicstaticint test2(){
  9.         int b =20;
  10.  
  11.         try{
  12.             System.out.println("try block");
  13.             return b +=80;
  14.         }catch(Exception e){
  15.             System.out.println("catch block");
  16.         } finally {
  17.             System.out.println("finally block");
  18.             if(b >25){
  19.                 System.out.println("b>25, b = "+ b);
  20.             }
  21.             return200;
  22.         }
  23.         // return b;
  24.     }
  25.  
  26. }
执行结果:
  1. try block
  2. finally block
  3. b>25, b =100
  4. 200
 
参考:http://www.cnblogs.com/lanxuezaipiao/p/3440471.html(博文代码用例4结果有误,见该博文讨论区分析)
 
 
 
 
 
 
 

JAVA try-catch-finally-return的更多相关文章

  1. java try catch finally return执行

    public static int testBasic(){ int i = 1; try{ i++; System.out.println("try block, i = "+i ...

  2. 【Java疑难杂症】有return的情况下try catch finally的执行顺序

    有这样一个问题,异常处理大家应该都不陌生,类似如下代码: public class Test { public static void main(String[] args) { int d1 = 0 ...

  3. 可惜Java中没有yield return

    项目中一个消息推送需求,推送的用户数几百万,用户清单很简单就是一个txt文件,是由hadoop计算出来的.格式大概如下: uid caller 123456 12345678901 789101 12 ...

  4. 异常 try catch finally return 执行关系 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. Java_try,catch,finally return之间的执行顺序

    以往认为函数只要执行到return语句便会返回结果并终止,然而这时错误的,因为这存在特例. 掌握下面几条原则就可以完全解决“当try.catch.finally遭遇return”的问题. 原则:1.f ...

  6. try catch finally return之间的关系

    一.try catch finally return之间的关系: 正在写dsoFramer的时候,同事突然说面试的时候问的一个问题,catch和return那个先执行,我瞬间迷茫了,然后整理了整理,稍 ...

  7. Intellij Idea 12 开发Android 报Caused by: java.lang.UnsatisfiedLinkError: FindLibrary return null;

    这次开发是用的百度地图api,导入两个so文件,结果启动的时候总是报Caused by: java.lang.UnsatisfiedLinkError: findlibrary return null ...

  8. Hint: Fallback method 'public java.lang.String queryUserByIdFallback(java.lang.Long)' must return: User or its subclass

    1.错误日志 熔断器添加错误方法返回时,报了一个 error. com.netflix.hystrix.contrib.javanica.exception.FallbackDefinitionExc ...

  9. try catch finally return运行顺序

    首先让我们搞懂两组概念:try catch finally和return 1.try catch finally 首先说try catch, (1)try语句 ,try语句用来包围可能出现异常的代码片 ...

  10. 理清Java中try-catch-finally带return的执行顺序

    前言:try-catch-finally带return和异常时,它们之间执行顺序问题是留下来的一个小疑问,今天搞清楚它们 第一种情况:无异常 //1.try-catch-finally都带有retur ...

随机推荐

  1. java学习——IO流

    字符流的由来:其实就是:字节流读取文字字节数据后,不直接操作而是先查指定的编码表.获取对应的文字.在对这个文字进行操作.简单说:字节流+编码表 ---------------------------- ...

  2. int, NSInteger, NSUInteger, NSNumber的区别

    新手在接触iOS或者Mac开发的时候,看到int和NSInteger,一般不清楚应该用哪个比较合适.我们先来查看下NSInteger的定义 #if __LP64__ || (TARGET_OS_EMB ...

  3. windows phone使用sharpcompress进行解压压缩文件

    在做移动端时,当我们需要从服务器获得多个文件时,为了节约流量,服务器一般会返回一个压缩包,那我们就是下载完成后,在手机中进行解压到指定位置 SharpCompress就是可以在手机中进行解压一个类库( ...

  4. Java学习----设计正真的应用程序

    import java.util.Scanner; // 输入10位学生的成绩,并且判断他们的成绩是哪个等级,其中90-100是A级,80-89是B级,70-79是C级,60-69是D级,60分以下E ...

  5. C++学习笔记5——类的继承

    简介: 通过继承联系在以前的类构成一种层次关系.通常在层次关系的根部有一个基类,其他类则直接或间接地从基类继承,这些继承得到的类称为类的派生类. 作用: 1.子类拥有父类的所有成员函数和成员变量. 2 ...

  6. 浅谈iOS视频播放的N种解决方案

    简       注册登录 添加关注 作者 Maru2016.03.22 20:46* 写了4349字,被135人关注,获得了207个喜欢 字数1621 阅读2895 评论43 喜欢159 header ...

  7. 使用cglib动态创建java类

    转至:http://ckwang17.iteye.com/blog/963881 cglib 是一个开源项目! 是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Jav ...

  8. 编写C# Windows服务,用于杀死Zsd.exe进程

    最近经常在我的xp系统进程中出现Zsd.exe进程.刚开始他占用内存不是很大.但是过了一段时间就会变成几百M 机器就会变得很卡,网上说Zsd可能是病毒.所以我就想要不写一个Windows服务,让他每隔 ...

  9. Chrome不支持NPAPI的信息与替代方案

    昨天Chrome稳定版更新到了42版,发现百度云.支付宝.网银等等的插件都失效了,打开 chrome://plugins/ 一看,NPAPI都消失了,只有flash的插件还在.解决办法是到 chrom ...

  10. 【HDOJ】4403 A very hard Aoshu problem

    HASH+暴力. /* 4403 */ #include <iostream> #include <cstdio> #include <cstring> #incl ...