当前位置:   article > 正文

Java异常及异常块执行次序(try、catch、finally、return)

java异常执行顺序

Java异常:

①使用try-catch-finally处理异常;

②使用throw、throws抛出异常;

③上边为java异常处理5个关键字。

异常是程序在设计时或运行时产生的错误,异常处理是处理异常的过程,一旦异常被处理后,异常就不存在了,因此程序就可以继续运行了。如果异常不被处理,程序就会被强制终止(终止出现异常的业务代码执行)。

在程序运行中,程序的try、catch、finally、return执行次序,就要进行考虑了

①:捕获异常

  1. try{
  2. //执行可能产生异常的代码
  3. }catch (Exception e) {
  4. //捕获异常,并处理
  5. }finally{
  6. //无论是否发生异常,代码总能执行
  7. }
  8. //other code
三种情况:

1:try代码块中无异常,try代码执行完成,则不进入不执行catch(跳过),执行finally块,及异常块后的其他代码other code;

2:try代码块中发生异常,try代码执行到有异常处即之后中断,产生异常对象(跟踪堆栈,执行流程),进入catch块(异常类型匹配后处理),后执行finally块,及异常块后的其他代码other code;

3:try代码块中发生异常,产生异常对象,异常类型不匹配,或者不捕获,程序中断运行(不用try和catch块进行处理,代码在异常出停止);

注:finally块语句唯一不执行的情况:异常处理代码catch中执行System.exit(1)退出Java虚拟机 ;

      一段代码可能会发生多种类型的异常,当发生异常,会按顺序查看每个catch语句,并执行第一个与异常类型匹配的catch块,执行后,其他的catch语句将忽略,执行继续执行finally块,及异常块后的其他代码other code。

②:throws声明异常,throw抛出异常
  1. //声明方法可能要抛出的各种异常(throws 多个之间用,隔开)
  2. public static int divide1(int x,int y) throws Exception{
  3. try{
  4. //...
  5. }catch (Exception e) {
  6. //此处自定义,手动抛出异常,对异常进行处理的代码段
  7. throw new Exception("Manual throws an exception");
  8. }finally{
  9. //...
  10. }
  11. return 0;
  12. }
注:代码抛出异常后,要在方法上声明可能发生的异常

看段代码,会执行出什么结果:

  1. //主方法
  2. public static void main(String[] args) {
  3. System.out.println(divide(20, 4));
  4. System.out.println(divide(20, 0));
  5. }
  6. //除法
  7. public static int divide(int x,int y){
  8. int result = 0;
  9. try{
  10. result = x / y;
  11. }catch (Exception e) {
  12. }finally{
  13. return -1;
  14. }
  15. return result;
  16. }
其实上边代码是不能被编译通过的:

错误1:

在return result;这一行;

Error:(remove) unreachable code(不能执行到的代码,因为finally在return前执行,return -1;所有代码已经结束,代码return result;则不会被执行)

警告1:

警告在finally块上:

finally块{ }中的代码:Warning:finally block does not complete normally(finally块不能正常完成,finally没有执行完毕就return了)

警告2:在注释掉,有错误的return result;行后.

警告在方法第一层局部变量:int result = 0;上:

局部变量result:Warning:(result)The value of the local variable result is not used(局部变量的值未被使用,在同级范围未被使用,可以在使用出定义更内部局部变量替代.)

错误代码//  return result;,注释掉后,代码:

执行结果为:

我是必须执行的finally!
返回结果:-1
java.lang.ArithmeticException: / by zero
at com.test.TryCatchFinally.testReturnFinallySort(TryCatchFinally.java:12)
at com.test.TryCatchFinally.main(TryCatchFinally.java:7)
我是异常处理日志:除数为空异常!/ by zero
我是必须执行的finally!
返回结果:-1

第二个- 1 ,因为,发生除数为0的算数异常(ArithmeticException),在catch中做了,空处理(只打印打印异常信息日志),所有不做业务异常处理,之后执行finally,所以为-1(两次都是它返回的.)

通过下边代码,现在来看看,try、catch、finally、return执行次序:

  1. public static void main(String[] args) {
  2. System.out.println("main output result:"+divide1(20, 0));
  3. }
  4. public static int divide1(int x,int y) {
  5. int result = 0;
  6. try{
  7. System.out.println("1 Execute the code before");
  8. result = x / y;
  9. System.out.println("2 Execute the code after");
  10. }catch (Exception e) {
  11. System.out.println("3 Abnormal block execution:"+e.getMessage());
  12. }finally{
  13. System.out.println("4 Has been performed");
  14. }
  15. return result;
  16. }
执行结果:

1 Execute the code before
3 Abnormal block execution:/ by zero
4 Has been performed
注:5 返回方法最终执行结果,此处异常处理,只为打印日志,返回result初始值0.

main output result:0

可以看出:

代码顺序为:执行try中要执行的代码,碰到异常,执行try中代码立即停止,进入catch中处理,处理完成后,进入finally中,最后return代码结束(整个代码正常执行);

下边代码为正常执行(不会进catch):

  1. public static void main(String[] args) {
  2. System.out.println("main output result:"+divide1(20, 4));
  3. }
  4. public static int divide1(int x,int y) {
  5. int result = 0;
  6. try{
  7. System.out.println("1 Execute the code before");
  8. result = x / y;
  9. System.out.println("2 Execute the code after");
  10. }catch (Exception e) {
  11. System.out.println("3 Abnormal block execution:"+e.getMessage());
  12. }finally{
  13. System.out.println("4 Has been performed");
  14. }
  15. return result;
  16. }
输出为:

1 Execute the code before
2 Execute the code after
4 Has been performed
main output result:5

下边为有异常,但不做异常处理代码:

  1. package com.tsXs.exception;
  2. public class TryCatchForCatchFinally {
  3. public static void main(String[] args) {
  4. System.out.println("main output result:"+divide1(20, 0));
  5. }
  6. public static int divide1(int x,int y) {
  7. int result = 0;
  8. try{
  9. System.out.println("1 Execute the code before");
  10. result = x / y;
  11. System.out.println("2 Execute the code after");
  12. }finally{
  13. System.out.println("4 Has been performed");
  14. }
  15.   System.out.println("5 continue codes."); return result;
  16. }
  17. }

控制台,输出为:

1 Execute the code before
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.tsXs.exception.TryCatchForCatchFinally.divide1(TryCatchForCatchFinally.java:10)
at com.tsXs.exception.TryCatchForCatchFinally.main(TryCatchForCatchFinally.java:4)
4 Has been performed
注:异常不被catch处理,则异常发生,程序中断运行,之后其他的代码5步和return都将不会被执行。

java异常结构:

Throwable为Exception和Error类的父类

Error为仅靠程序本身无法恢复的严重错误

Exception为由Java应用程序抛出和处理的非严重错误

RuntimeException运行时异常可以不处理,在编程时应该多考虑,尽量的避免发生

RuntimeException之外的其他异常,设计时异常必须处理,还包括自定义业务异常

注:

异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,JVM就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。 异常只能用于错误处理,不应该(建议)用来控制程序流程。

注:错误业务纠正,如果您是做业务需求的话,进入catch之后,如果不写入错误业务处理代码(代码效率低),只打印日志,则应该return停止业务,不然的话,catch块后的代码将会一直执行,导致业务出现错误!看以下代码:

  1. /**
  2. * 测试:异常被处理catch后,是否继续执行
  3. * */
  4. public static void testCodeContinue(){
  5. int i = 8, h = 0,k = 0;
  6. int j = i + h;
  7. System.out.println(i+"+"+h+"的和为:" + j);
  8. try {
  9. k = i / h;
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. System.err.println("我是异常处理日志:除数为空异常!"+e.getMessage());
  13. //return 返回停止业务代码执行
  14. }finally{
  15. System.out.println("我是必须执行的finally!");
  16. }
  17. System.out.println("我是异常块后的继续代码……");
  18. int l = i * h;
  19. System.out.println(i+"*"+h+"的积为:"+l);
  20. }



执行结果:

8+0的和为:8
java.lang.ArithmeticException: / by zero
 at com.test.TryCatchFinally.testCodeContinue(TryCatchFinally.java:16)
 at com.test.TryCatchFinally.main(TryCatchFinally.java:5)
我是异常处理日志:除数为空异常!/ by zero
我是必须执行的finally!
我是异常块后的继续代码……
8*0的积为:0

如果出现错误被return,则:

  1. /**
  2. * 测试:异常被处理catch后,是否继续执行
  3. * */
  4. public static void testCodeContinue(){
  5. int i = 8, h = 0,k = 0;
  6. int j = i + h;
  7. System.out.println(i+"+"+h+"的和为:" + j);
  8. try {
  9. k = i / h;
  10. } catch (Exception e) {
  11. e.printStackTrace();
  12. System.err.println("我是异常处理日志:除数为空异常!"+e.getMessage());
  13. //return 返回停止业务代码执行
  14. return ;
  15. }finally{
  16. System.out.println("我是必须执行的finally!");
  17. }
  18. System.out.println("我是异常块后的继续代码……");
  19. int l = i * h;
  20. System.out.println(i+"*"+h+"的积为:"+l);
  21. }

 

执行结果为:

8+0的和为:8
java.lang.ArithmeticException: / by zero
 at com.test.TryCatchFinally.testCodeContinue(TryCatchFinally.java:53)
 at com.test.TryCatchFinally.main(TryCatchFinally.java:7)
我是异常处理日志:除数为空异常!/ by zero
我是必须执行的finally!
这儿也可以看出,finally在return之前执行.此代码,因为return而终止执行!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/252832
推荐阅读
相关标签
  

闽ICP备14008679号