一、异常的概念

异常、错误的概念以及区别

  • 异常是不正常的事件,不是错误
  • 异常是指程序运行的过程中,发生某些以外的事故,比如 10 除以 0,文件不存在等

二、错误的概念

  • 错误是比较难处理的,比如内存溢出,不能通过异常处理机制来解决

image.png

  • 异常的程序中发生的不正常事件流,通过处理程序依然可以运行下去。但是错误无法控制,程序肯定会中断

三、API 中的异常

3.1 异常的体系

Throwab le类有两个直接子类: Exception类、Error类。Error表示错误,可能是编译期错误或者系统错误,往往 程序中并不处理。Exception表示异常, 是所有异常类的父类,是程序员所关心的。 image.png

3.2 异常的种类

  • 异常分为 运行期异常 和 编译期异常两种
    • 运行期异常:程序运行时抛出异常,所有 RuntimeException 的子类都是运行期异常
      • 数学异常
      • 空指针异常
      • 数组下标越界异常
    • 编译期异常(Checked Exception):除去运行期的异常都是编译期异常,也成为检查异常
      • IOException
      • SQLException
      • 3.3 标准异常体系

        image.png

        3.4 常用异常

        image.png

四、异常捕获 (try catch finally)

4.1 try 的定义和使用

  • 检测不安全的代码库 (发现异常)
  • try 块中任何一条语句发生了异常,下面的代码将不会执行,程序将不会被执行,程序将跳到异常处理的代码块中,即 catch 块。因此不能随意将不相关的代码放到 try块中,因为随时可能中断执行
  1. try {
  2. 代码块
  3. }

4.2 catch的定义和使用

  • 把抓到的类型匹配的异常捕获,保证程序可以正常运行下去
  • catch 语句必须紧跟着 try 语句,称为捕获异常,也就是异常处理函数,一个 try 后面可以写多个 catch,分别捕获不同类型的异常,要从子类往父类顺序写,否则有编译错误
  1. catch (异常类型 引用名) {
  2. }
  3. // catch 可以跟多个
  4. try {
  5. xxxx
  6. } catch (NullPointerException e) { // 捕获子类异常
  7. } catch (Exception e) { // 捕获父类异常
  8. }

4.3 finally的定义和使用

  • finally 改内容总是会执行,而且只能有一个 finally 语句
  1. finally {
  2. 必须执行的逻辑
  3. }

4.4 基本语法

  1. try {
  2. 可能发生的异常代码
  3. } catch (异常类型 引用名) {
  4. 异常处理代码
  5. } finally {
  6. 必须执行代码
  7. }
  1. try {
  2. String a = null ;
  3. System.out.println(a.split("a")) ;
  4. System.out.println("执行 try 语句");
  5. } catch (NullPointerException e) {
  6. System.out.println("空指针异常");
  7. e.printStackTrace() ;
  8. } catch (Exception e) {
  9. System.out.println("发生异常了");
  10. e.printStackTrace();
  11. } finally {
  12. System.out.println("执行结束");
  13. }

image.png

五、finally 和 return

finally 是强制执行,无论如何 finally 都会执行,然后才会执行 return

5.1 return 会阻止 finally 执行吗?

  1. main 方法省略,只写核心代码
  2. try {
  3. System.out.println("执行 try 语句");
  4. String a = null ;
  5. System.out.println(a.length()) ;
  6. return ;
  7. } catch (NullPointerException e) {
  8. System.out.println("空指针异常");
  9. } finally {
  10. System.out.println("执行结束");
  11. }
  12. System.out.println("main 结束了");

image.png

答案是并不会

5.2 强制退出 System.exit(0)

        try {
            System.out.println("执行 try 语句");
            String a = null ;
            System.out.println(a.length()) ;
        } catch (NullPointerException e) {
            System.out.println("空指针异常");
            System.exit(0); // 强制退出 JVM 虚拟机
            System.out.println("我不会执行了");
        }  finally {
            System.out.println("执行结束");
        }
        System.out.println("main 结束了");

六、throw 和 thorws、层层抛出异常

6.1 thorw

  • throw 用于显示抛出异常
  • 抛出异常后处理
    • 使用 try-catch 捕获异常
    • 使用 throws 声明异常
  • 语法 throw new 异常类构造方法
  • 例如 throw new Exception();

  • 利用抛出异常来标记不正常的事件,从而对事件流统一处理

static int avg(int n1, int n2) throws Exception {
     if (n1<0 || n2<0) // 判断是否满足条件
    {
        throw new Exception("不能使用负数");
    }
    if (n1>100 || n2>100) {
         throw new Exception("数值太大了!");   
    }
    return (n1+n2)/2;
}

6.2 throws

  • 用于方法声明处,指出方法引出的异常
  • 可以声明多种异常类型,用逗号分开即可
  • 示例
public void test throws NullPointerException,Exception.... {

}
  • 任何方法都可以使用 throws 关键字声明异常类型,包括抽象方法
  • 子类覆盖父类中的方法,子类方法不能声明抛出比父类范围更大的异常
  • 使用了 throws 方法,调用时必须处理声明的异常,要么使用 try-catch,要么继续使用 throws

    6.3 层层抛出异常举例

public class cal {
    //除法计算
    //b不能为0
    public void calc(int a,int b) throws Exception {
        if(b==0){
            try {
                throw  new Exception("有异常哦!!!!");
            } catch (Exception e) {
                System.out.println("有异常哦!!!!");
                //现在这里抛出一个有异常的提示,具体的异常可在调用时再抛出
                throw e;
            }
        }
        else{
            System.out.println(a/b);
        }
    }
}

public class io异常 {
    public static void main(String[] args)throws Exception{
        cal ac=new cal();
        try {
           ac.calc(5,0);
        } catch (Exception e) {
           System.out.println("输入的除数不能为0!!!!");
        }
    }
}

6.3 总结

  1. 使用 throws 抛出异常
  2. 或者 try-catch 捕获异常

    七、自定义异常

  • 自定义异常类
  • 自定义异常类往往不写其他方法,只重载需要使用的构造方法
    // 该类中不会写方法
    public class 异常类名 extends Exception     {
      public 异常类名(String msg) {
           super(msg);   
      }
    }}