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);
    }
}


posted @ 2020-11-26 23:13  羊37  阅读(110)  评论(0编辑  收藏  举报