• Java中的异常处理3_异常的抛出


    1.结论

    调用某个方法时,能否catch住异常,取决于调用的该方法在执行过程中是否有对应的异常抛出来.

    2.示例

    2.1自定义异常类MyException

    package cn.yang37.zother.myexception;
    
    /**
     * @Description:
     * @Class: MyException
     * @Author: Yiang37
     * @Date: 2020/11/26 21:22
     * @Version: 1.0
     */
    public class MyException extends RuntimeException{
    
        //自定义异常通常实现这两个构造方法
        public MyException() {
        }
    
        public MyException(String message) {
            super(message);
        }
    }
    

    2.2测试类ExceptionTest

    单单只去用try-catch捕获,并不一定真的就靠谱,两段代码的区别仅仅在于doSome()方法内部(42行)的处理不同.

    	....
        //两段代码的main方法是一样的,都是尝试执行 invokeDoSome()方法,出现异常后不进行后续操作
        public static void main(String[] args) {
            try {
              //假设invokeDoSome()是帮助我向数据库插入一条记录;
              invokeDoSome(1);
            } catch (Exception e) {
                System.out.println("若有该行,证明主方法能捕获到异常,捕获到异常:"+e.getMessage());
                System.out.println("出现异常后,我知道不再进行业务逻辑...");
                return;
            }
            
            System.out.println("我认为invokeDoSome帮我向数据库插入了一条记录,代码继续运行,于是我开始进行下一步逻辑...");
        }
    	....
    

    2.2.1测试类:内部catch后不抛出异常

    package cn.yang37.zother.myexception;
    
    /**
     * @Description:
     * @Class: ExceptionTest
     * @Author: Yiang37
     * @Date: 2020/11/26 21:27
     * @Version: 1.0
     */
    public class ExceptionTest {
    
        //1.主方法
        public static void main(String[] args) {
            try {
              //假设invokeDoSome()是帮助我向数据库插入一条记录;
              invokeDoSome(1);
            } catch (Exception e) {
                System.out.println("若有该行,证明主方法能捕获到异常,捕获到异常:"+e.getMessage());
                System.out.println("出现异常后,我知道不再进行业务逻辑...");
                return;
            }
            
            System.out.println("我认为invokeDoSome帮我向数据库插入了一条记录,代码继续运行,于是我开始进行下一步逻辑...");
        }
        
        
        //2.invokeDoSome方法 调用了doSome方法
        public static String invokeDoSome(int num){
            return doSome(num);
        }
        
        //3.doSome方法
        public static String doSome(int num) {
    
            System.out.println("doSome开始执行");
    
            /*假设我们不知道他内部的处理逻辑 只知道某种情况会抛出异常*/
            try {.....}
            catch (Exception e) {
                //catch不抛出 打印信息并返回执行错误
                System.out.println(e.getMessage());
                return "error";
            }
            return "success";
        }
    
    }
    

    执行结果

    doSome开始执行
    doSome()执行出错
    我认为invokeDoSome帮我向数据库插入了一条记录,代码继续运行,于是我开始进行下一步逻辑...
    

    2.2.2测试类:内部catch后抛出异常

    package cn.yang37.zother.myexception;
    
    /**
     * @Description:
     * @Class: ExceptionTest
     * @Author: Yiang37
     * @Date: 2020/11/26 21:27
     * @Version: 1.0
     */
    public class ExceptionTest {
    
        //1.主方法
        public static void main(String[] args) {
            try {
                //假设invokeDoSome()是帮助我向数据库插入一条记录;
                invokeDoSome(1);
            } catch (Exception e) {
                System.out.println("若有该行,证明主方法能捕获到异常,捕获到异常:"+e.getMessage());
                System.out.println("出现异常后,我知道不再进行业务逻辑...");
                return;
            }
            
            System.out.println("我认为invokeDoSome帮我向数据库插入了一条记录,代码继续运行,于是我开始进行下一步逻辑...");
        }
        
        
        //2.invokeDoSome方法 调用了doSome方法
        public static String invokeDoSome(int num){
            return doSome(num);
        }
        
        //3.doSome方法
        public static String doSome(int num) {
    
            System.out.println("doSome开始执行");
    
            /*假设我们不知道他内部的处理逻辑 只知道某种情况会抛出异常*/
            try {.....}
            catch (Exception e) {
                //catch后抛出 打印信息 抛出异常
                System.out.println(e.getMessage());
                throw new MyException("由doSome()抛出的MyException");
            }
            return "success";
        }
    
    }
    

    执行结果

    doSome开始执行
    doSome()执行出错
    若有该行,证明主方法能捕获到异常,捕获到异常:由doSome()抛出的MyException
    出现异常后,我知道不再进行业务逻辑...
    

    3.结果说明

    A 同样是调用doSome()的过程中doSome()执行出现了错误,只是由于前者的doSome()方法未抛出异常,就导致main()方法运行的结果不一样.

    B 深层代码不抛出异常时,直接catch是无法捕捉的.

    来对比下

    • 不抛出异常
    doSome开始执行
    doSome()执行出错
    我认为invokeDoSome帮我向数据库插入了一条记录,代码继续运行,于是我开始进行下一步逻辑...
    
    • 抛出异常
    doSome开始执行
    doSome()执行出错
    若有该行,证明主方法能捕获到异常,捕获到异常:由doSome()抛出的MyException
    出现异常后,我知道不再进行业务逻辑...
    

    在前一种情况里面,我们以为执行出错时能在catch进行处理,开始下一步的代码编写...然而doSome()已经出现了错误.

    如果我们调用的是一个内部未抛出异常的方法,以为直接用最厉害的catch(Exception e)能抓住一切,其实是危险的写法.

    4.原因分析

    4.1为何内部的doSome()不去抛出异常让我们知道?

    今天有点晚了,以后再完善...

    4.2当内部不抛出异常而只给出返回值(前者)时,如何确保安全?

    此时修改主方法的代码

        public static void main(String[] args) {
    
            try {
                //尝试调用一个不知道情况的doSome()方法
               String res =  invokeDoSome(1);
               if ("error".equals(res)){
                   throw new Exception("invokeDoSome的插入表操作是失败的!");
               }
               
            } catch (Exception e) {
                System.out.println("若有该行,证明主方法能捕获到异常,捕获到异常:"+e.getMessage());
                System.out.println("出现异常后,我知道不再进行业务逻辑...");
                return;
            }
    
            System.out.println("我认为invokeDoSome帮我向数据库插入了一条记录,代码继续运行,于是我开始进行下一步逻辑...");
        }
    

    执行结果

    doSome开始执行
    doSome()执行出错
    若有该行,证明主方法能捕获到异常,捕获到异常:invokeDoSome的插入表操作是失败的!
    出现异常后,我知道不再进行业务逻辑...
    

    5.附源码用于调试

    package cn.yang37.zother.myexception;
    
    /**
     * @Description:
     * @Class: ExceptionTest
     * @Author: Yiang37
     * @Date: 2020/11/26 21:27
     * @Version: 1.0
     */
    public class ExceptionTest {
    
        public static void main(String[] args) {
    
            try {
                //尝试调用一个不知道情况的doSome()方法
               String res =  invokeDoSome(1);
               if ("error".equals(res)){
                   throw new Exception("invokeDoSome的插入表操作是失败的!");
               }
    
            } catch (Exception e) {
                System.out.println("若有该行,证明主方法能捕获到异常,捕获到异常:"+e.getMessage());
                System.out.println("出现异常后,我知道不再进行业务逻辑...");
                return;
            }
    
            System.out.println("我认为invokeDoSome帮我向数据库插入了一条记录,代码继续运行,于是我开始进行下一步逻辑...");
        }
    
        //doSome()会抛出一个自定义的异常
        public static String doSome(int num) {
    
            System.out.println("doSome开始执行");
    
            /*假设我们不知道他内部的处理逻辑 只知道某种情况会抛出异常*/
            try {
                if (num % 2 != 0){
                    throw new MyException("doSome()执行出错");
                }
    
            //它某种情况下抛出了一个异常
            }
            catch (Exception e) {
                System.out.println(e.getMessage());
                return "error";
    //            throw new MyException("由doSome()抛出的MyException");
            }
    
            return "success";
        }
    
        public static String invokeDoSome(int num){
            return doSome(num);
        }
    }
    
    
    
  • 相关阅读:
    这样的UI UX设计师描述你满意吗?
    原型设计建议规范(二)
    优质产品需求文档(PRD)写作三大原则
    一流用户体验设计师的6个共同点
    在原型设计上,UI和UX设计师有哪三个区别?
    UI设计:掌握这6点,轻松0到1
    优秀UX设计师的八条黄金法则
    hdu1686Oulipo(KMP)
    hdu1711Number Sequence(KMP)
    hdu2612Find a way
  • 原文地址:https://www.cnblogs.com/yang37/p/14045302.html
Copyright © 2020-2023  润新知