Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 376|回复: 0

java中异常与return

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-7-10 14:02:42 | 显示全部楼层 |阅读模式

    抽时间整理了下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;
                    }
                }
            }
        }
    
    }

     

     

     

     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-1 05:56 , Processed in 0.060012 second(s), 28 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表