java中异常与return

抽时间整理了下java中异常与return,以前这块总是弄混淆,觉得还是写下来慢慢整理比较好。由于水平有限,仅供参考。废话不多说,直接上代码。

下面是两个方法:

 1      public static int throwReturn(){
 2         int ret = 0;
 3         try{
 4             ret = 10/0 ;
 5             ret++;
 6             return ret;
 7         }catch(Exception e){
 8             System.out.println("catch block " + e.getMessage());
 9             //ret++;
10             return ret;
11         }finally{
12             System.out.println("finally block invoked!!!");
13             ret++;
14             System.out.println("finally block invoked, ret is " + ret);
15         }
16         
17     }  
 1    public static int finallyReturn(){
 2         int ret = 0;
 3         try{
 4             ret = 10/0 ;
 5             ret++;
 6             return ret;
 7         }catch(Exception e){
 8             System.out.println("catch block " + e.getMessage());
 9             //ret++;
10             return ret;
11         }finally{
12             System.out.println("finally block invoked!!!");
13             ret++;
14             System.out.println("finally block invoked, ret is " + ret);
15             return ret;
16         }
17         
18     }

然后在主方法中分别调用两个方法:

1 public static void main(String args[]){
2   System.out.println("throwReturn:" + throwReturn());
3   //System.out.println("finallyReturn:" + finallyReturn());  
4 }

第一个方法输出结果:

catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
throwReturn:0

throwRetrun方法返回的结果并不是我预想的1,而是0。

个人分析:

  1. 程序执行到throwReturn方法的第4行时由于除0而出错,程序进入catch块,首先会执行打印输出:catch block / by zero
  2. 接下来会执行catch块的return ret语句,碰到return语句方法会返回退出,而finally语句又是必须执行的,此时程序会将return的结果值暂存起来,继续执行finally块。
  3. 进入finally块后会输出:finally block invoked!!! 和finally block invoked, ret is 1
  4. finally块执行完成后程序会回到return处,并返回当时暂存的值

第二个方法的输出结果:

catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
finallyReturn:1

哎,这次的输出结果是1了。

仔细比较两个方法发现第二个方法,在finally语句中多了一个return ret;程序的执行过程同上面基本上是一样的,只是在最终执行finally代码块是碰到了return语句,此时程序就直接将ret的值返回了,而此时ret的值是1,最后输出:finallyReturn:1

接下来我们再看2个方法:

 

 1     public static int throwException() throws Exception{
 2         int ret = 0;
 3         try{
 4             ret = 10/0 ;
 5             System.out.println("ret:" + ret);
 6             return ret;
 7         }catch(Exception e){
 8             System.out.println("catch block " + e.getMessage());
 9             throw e;
10         }finally{
11             System.out.println("finally block invoked!!!");
12             ret++;
13             System.out.println("finally block invoked, ret is " + ret);
14         }
15         
16     }

 

 1 public static int finallyThrowException() throws Exception{
 2         int ret = 0;
 3         try{
 4             ret = 10/0 ;
 5             System.out.println("ret:" + ret);
 6             return ret;
 7         }catch(Exception e){
 8             System.out.println("catch block " + e.getMessage());
 9             throw e;
10         }finally{
11             System.out.println("finally block invoked!!!");
12             ret++;
13             System.out.println("finally block invoked, ret is " + ret);
14             return ret;
15         }
16         
17     }

然后在主方法中分别调用两个上面方法:

 

 1 public static void main(String args[]){
 2        try {
 3             System.out.println("throwException:" + throwException());
 4         } catch (Exception e) {
 5             System.out.println("捕获到throwException方法抛出的异常," + e.getMessage());
 6         } 
 7 
 8         /*try {
 9             System.out.println("finallyThrowException:" + finallyThrowException());
10         } catch (Exception e) {
11             System.out.println("捕获到finallyThrowException方法抛出的异常," + e.getMessage());
12         }*/     
13 }

 

第一个方法输出结果:

catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
捕获到throwException方法抛出的异常,/ by zero

个人分析:

  1. throwException方法执行到第4行时,因为除0操作抛出异常,程序进入catch块,首先执行打印输出:catch block / by zero
  2. 接下来会执行catch块的throw e语句,向上抛出异常,而finally语句又是必须执行的,此时程序会先执行finally块。
  3. 进入finally块后会输出:finally block invoked!!! 和finally block invoked, ret is 1
  4. finally块执行完成后程序会回到catch块throw处,将捕获的异常向上抛出
  5. 在main方法中会捕获到throwException方法抛出的异常而进入catch块,所以会输出:捕获到throwException方法抛出的异常,/ by zero

第二个方法的输出结果:

 

catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
finallyThrowException:1

 

观察输出结果会发现,主方法并没有捕获到finallyThrowException方法调用时的异常(catch块的打印没有执行)。

这两个方法的主要区别也是在于:在finallyThrowException方法的finally块中多出了return ret语句。调用finallyThrowException方法的执行过程同调用throwException方法基本一致。

  1. finallyThrowException方法执行时,因为除0操作抛出异常,程序进入catch块,首先执行打印输出:catch block / by zero
  2. 接下来会执行catch块的throw e语句,向上抛出异常,而finally语句又是必须执行的,此时程序会先执行finally块。
  3. 进入finally块后会输出:finally block invoked!!! 和finally block invoked, ret is 1
  4. finally块执行到return ret时,该方法直接返回了ret的值,
  5. 在main方法中得到finallyThrowException的返回值后输出:finallyThrowException:1

finallyThrowException方法执行结果可以看出方法执行时的异常被丢失了


最后再来看一个小例子

 1 public static void finallyWork(){
 2         int count = 0;
 3         while(true){
 4             try{
 5                 if(count++ == 0){
 6                     throw new Exception("my error");
 7                 }
 8                 System.out.println("invoked ...");
 9             }catch(Exception e){
10                 System.out.println("catched exception:" + e.getMessage());            
11             }finally{
12                 System.out.println("finally block invoked!!!");
13                 if(count == 2){
14                     break;
15                 }
16             }
17         }
18     }

这个小例子的主要思路是当java中的异常不允许我们回到异常抛出的地点时,我们可以将try块放到循环里,这样程序就又可以回到异常的抛出点了,可以同时设置一个计数器,当累积尝试一定的次数后程序就退出。

ok,就说这么多了,下面附上完整代码:

package tt;public class FinallyWorks {/*** @param args*/public static void main(String[] args) {//finallyWork();/**<output begin>*        catch block / by zero*        finally block invoked!!!*        finally block invoked, ret is 1*          throwReturn:0*</output end>*从输出结果中可以看出程序在int temp = 10/0;这一行抛出异常,直接进入catch块,首先输出打印catch block...,继续往下执行时碰到return语句,由于程序*存在finally语句,在程序返回之前需要执行finally语句。那么此时程序会将return的结果值暂时存起来,继续执行finally,从输出上可以看出finally执行后ret*的值变为了1,而整个方法最终的返回结果是0,说明return的是之前暂存的值。* *///System.out.println("throwReturn:" + throwReturn());/** <output begin>*        catch block / by zero*        finally block invoked!!!*        finally block invoked, ret is 1*          finallyReturn:1*</output end>*从输出结果中可以看出程序在int temp = 10/0;这一行抛出异常,直接进入catch块,首先输出打印catch block...,继续往下执行时碰到return语句,由于程序*存在finally语句,在程序返回之前需要执行finally语句。那么此时程序会将return的结果值暂时存起来,继续执行finally,从输出上可以看出finally执行后ret*的值变为了1,有在finally块中碰到了return语句,方法就直接返回了,所以方法结果返回了1。* *///System.out.println("finallyReturn:" + finallyReturn());/**<output begin>*        catch block / by zero*        finally block invoked!!!*        finally block invoked, ret is 1*          捕获到throwException方法抛出的异常,/ by zero*</output end>*从输出结果中可以看出在调用throwException方法是出现异常,程序进入该方法的catch块中,输出:catch block / by zero*由于存在finally,程序会先执行完finally语句输出:finally block invoked!!! 和 finally block invoked, ret is 1*然后将捕获到的异常抛向上层。上层的main方法catch到这个异常之后会输出:捕获到throwException方法抛出的异常,/ by zero*《注意throwException:那句打印是不会输出的》* *//*try {System.out.println("throwException:" + throwException());} catch (Exception e) {System.out.println("捕获到throwException方法抛出的异常," + e.getMessage());}*//**<output begin>*           catch block / by zero*        finally block invoked!!!*        finally block invoked, ret is 1*          finallyThrowException:1*</output end>*从输出结果中可以看出在调用finallyThrowException方法是出现异常,程序进入该方法的catch块中,输出:catch block / by zero*由于存在finally,程序会先执行完finally语句输出:finally block invoked!!! 和 finally block invoked, ret is 1*之后程序执行到finally块中return语句,直接返回了ret的值,主方法接受到这个返回值后输出:finallyThrowException:1*《注意主方法中catch块代码并没有被执行,这就说明了finallyThrowException方法中异常被丢失了》* */try {System.out.println("finallyThrowException:" + finallyThrowException());} catch (Exception e) {System.out.println("捕获到finallyThrowException方法抛出的异常," + e.getMessage());}}public static int throwException() throws Exception{int ret = 0;try{ret = 10/0 ;System.out.println("ret:" + ret);return ret;}catch(Exception e){System.out.println("catch block " + e.getMessage());throw e;}finally{System.out.println("finally block invoked!!!");ret++;System.out.println("finally block invoked, ret is " + ret);}}public static int finallyThrowException() throws Exception{int ret = 0;try{ret = 10/0 ;System.out.println("ret:" + ret);return ret;}catch(Exception e){System.out.println("catch block " + e.getMessage());throw e;}finally{System.out.println("finally block invoked!!!");ret++;System.out.println("finally block invoked, ret is " + ret);return ret;}}public static int throwReturn(){int ret = 0;try{ret = 10/0 ;ret++;return ret;}catch(Exception e){System.out.println("catch block " + e.getMessage());//ret++;return ret;}finally{System.out.println("finally block invoked!!!");ret++;System.out.println("finally block invoked, ret is " + ret);}}public static int finallyReturn(){int ret = 0;try{ret = 10/0 ;ret++;return ret;}catch(Exception e){System.out.println("catch block " + e.getMessage());//ret++;return ret;}finally{System.out.println("finally block invoked!!!");ret++;System.out.println("finally block invoked, ret is " + ret);return ret;}}/*** 当java中的异常不允许我们回到异常抛出的地点时,我们可以将try块放到循环里,* 这样程序就又可以回到异常的抛出点了,可以同时设置一个计数器,* 当累积尝试一定的次数后程序就退出。*/public static void finallyWork(){int count = 0;while(true){try{if(count++ == 0){throw new Exception("my error");}System.out.println("invoked ...");}catch(Exception e){System.out.println("catched exception:" + e.getMessage());            }finally{System.out.println("finally block invoked!!!");if(count == 2){break;}}}}}

 

 

 

 

 

转载于:https://www.cnblogs.com/pengkw/archive/2012/11/22/2783342.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/576180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rocketmq 启动mqbroker.cmd闪退

非常奇怪&#xff0c;broker启动闪退&#xff0c;我就摸索了好久&#xff0c;网上各种百度&#xff0c;最后得到正解 将c盘下这个store下的文件全部删除&#xff0c;就可以启动了 猜测是可能mq非正常关闭&#xff0c;导致&#xff0c;具体懂原理的大佬可以来评论区说说

星星计算器

星星计算器&#xff1a; [ 机锋下载 ]第一款&#xff0c;呃&#xff0c;…&#xff0c;自家学习安卓的时候产的&#xff0c;功能和第二款有些类似&#xff08;而且在细节功能方面我也做了很多努力&#xff09;&#xff0c;不过已经十分强大了&#xff0c;并且有自己的创新&…

java基础复习-(run方法和start方法区别)

1&#xff0c;run方法是Runnable接口中定义的&#xff0c;start方法是Thread类定义的。 所有实现Runnable的接口的类都需要重写run方法&#xff0c;run方法是线程默认要执行的方法&#xff0c;是绑定操作系统的&#xff0c;也是线程执行的入口。 start方法是Thread类的默认执行…

Web.py Cookbook 简体中文版 - 如何使用web.background

注意&#xff01;&#xff01; web.backgrounder已转移到web.py 3.X实验版本中&#xff0c;不再是发行版中的一部分。你可以在这里下载&#xff0c;要把它与application.py放置在同一目录下才能正运行。 介绍 web.background和web.backgrounder都是python装饰器&#xff0c;它可…

为什么wait, notify,notifyAll保存在Object类中,而不是Thread类

一个较难回答的 Java 问题&#xff0c; Java 编程语言又不是你设计的&#xff0c;你如何回答这个问题呢&#xff1f; 需要对 Java 编程的常识进行深入了解才行。 这个问题的好在它能反映面试者是否对 wait - notify 机制有没有了解, 以及他相关知识的理解是否明确。就像为什么…

Springboot集成MapperFactory(ma.glasnost.orika.MapperFactory)类属性复制

导入jar <dependency><groupId>ma.glasnost.orika</groupId><artifactId>orika-core</artifactId><version>1.5.2</version></dependency> 编写容器注入的类 package com.kingboy.springboot.config;import ma.glasnost.or…

WPF之布局

此文目的旨在让人快速了解&#xff0c;没有什么深度&#xff0c;如需深入了解布局&#xff0c;请参考msdn。 如果你要把WPF当winform使用&#xff0c;拖拖控件也无不可&#xff0c;不过建议还是不要拖的好。 本文将那些用的比较多的几个布局控件&#xff08;Grid、UniformGrid、…

@Size、@Max、@Min、@Length、注解的含义和区别

Min 验证 Number 和 String 对象是否大等于指定的值Max 验证 Number 和 String 对象是否小等于指定的值Size(min, max) 验证对象&#xff08;Array,Collection,Map,String&#xff09;长度是否在给定的范围之内Length(min, max) 验证字符串长度是否在给定的范围之内区别&#x…

C# WCF WinCE 解决方案 错误提示之:已超过传入消息(65536)的最大消息大小配额。若要增加配额,请使用相应绑定元素上的 MaxReceivedMessageSize 属性...

C# WCF WinCE 解决方案 错误提示之&#xff1a;已超过传入消息(65536)的最大消息大小配额。若要增加配额&#xff0c;请使用相应绑定元素上的 MaxReceivedMessageSize 属性 网上的解决方案&#xff1a; 出现这种错误&#xff0c;先去修改服务器端和客户端的MaxReceivedMessageS…

mybatis xml返回对象类型和接口定义类型不一致

最近在开发中发现xml定义的返回值类型xxxxMaper.xml <select id"selectPlanList" parameterType"Plan" resultMap"PlanListVo">select * from table_name</select> <resultMap type"com.demo.vo.PlanListVo" id"…

算法可视化

http://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html http://jsrun.it/norahiko/oxIy转载于:https://www.cnblogs.com/hailuo/archive/2012/12/06/2805400.html

Springboot @Validated和@Valid的区别 及使用

Valid是使用Hibernate validation的时候使用 Validated是只用Spring Validator校验机制使用 说明&#xff1a;java的JSR303声明了Valid这类接口&#xff0c;而Hibernate-validator对其进行了实现 Validation对Valid进行了二次封装&#xff0c;在使用上并没有区别&#xff0c…

【dp】CF17C. Balance

http://codeforces.com/problemset/problem/17/C 题目中给出一个仅含有a,b,c的字符串&#xff0c;已经两种操作每次选出任意两个相邻的字符&#xff0c;用第一个覆盖掉第二个或者反之&#xff0c;最后询问不考虑操作次数&#xff0c;最终有多少种不同的序列其中a&#xff0c;b,…

git常用的命令收集

1.强制推送&#xff08;慎用&#xff0c;除非你认为其他冲突等可以丢弃 或者不是很重要&#xff09;git push -- force git—全局设置用户名、密码、邮箱 git config命令的–global参数&#xff0c;用了这个参数&#xff0c;表示你这台机器上所有的Git仓库都会使用这个配置&…

git文件操作命令

1.创建文件等小命令 touch a // 创建一个a文件 echo 1234 >> a // 把1234这个内容放入a文件 cat a // 打开a文件 读取出a文件中的内容 mkdir test // 创建test文件夹 rm 文件名 // 删除文件 pwd // 打印当前工作路径2.安装git的时候 都会安装git bash和git GUI 我们完全也…

ECSHOP设置默认配送方式和默认支付方式

用过ECSHOP的站长都知道&#xff0c;首次登陆ECSHOP进行购物的时候&#xff0c;购物流程中没有“默认配送方式和默认支付方式”这个功能 即使网站上只有一种配送方式&#xff0c;它也不会默认选中这个唯一的配送方式。 当你的网站只有一种配送方式&#xff0c;或者&#xff0c;…

spring如何解决循环依赖

什么是循环依赖&#xff1f; 循环依赖其实是指两个及以上bean相互持有对方&#xff0c;最终形成闭环的过程&#xff08;一般聊循环依赖都是默认的单例bean&#xff09;&#xff0c;简单说就是A依赖B,B依赖C,C又依赖A。 下面我就借用别人的网图来解释下&#xff1a; 注意&#…

利用Frame Animation实现动画效果,代码正确,就是达不到变换效果

就是因为把第一帧图片设置成了ImageView的src资源&#xff0c;从而一直覆盖在变换效果之上&#xff0c;去掉ImageView的src属性即可解决。 要想使应用已载入便播放动画效果&#xff0c;直接将 animationDrawables.start(); 放在activity的各种回调函数中&#xff08;onCreate、…

【电信增值业务学习笔记】3 语音类增值业务

作者&#xff1a;gnuhpc 出处&#xff1a;http://www.cnblogs.com/gnuhpc/ 1.一卡多号&#xff1a;&#xff08;Single SIM Multiple Number -SSMN&#xff09; 为拥有一个SIM卡的移动用户提供多个电话号码作为副号码主叫&#xff1a;可以选择用主号码还是副号码发起呼叫被叫&a…

循环依赖源码深度解析

singletonObjects &#xff08;一级缓存&#xff09;它是我们最熟悉的朋友&#xff0c;俗称“单例池”“容器”&#xff0c;缓存创建完成单例Bean的地方。 earlySingletonObjects&#xff08;二级缓存&#xff09;映射Bean的早期引用&#xff0c;也就是说在这个Map里的Bean不是…