Java|异常处理机制

一、什么是异常

  • 异常指程序运行中出现的各种各样的错误,如:文件找不到、网络连接失败、非法参数等。
  • 异常有些是用户错误引起的,有些是程序错误引起的,有些是物理错误引起的
  • 异常是一个事件,它发生在程序运行期间,中断了正在执行的程序的正常指令流。

二、异常的种类

  • 检查性异常(CheckedException)

    • 程序员不可预见的
    • 典型的如用户输入错误
    • 编译时不能忽略
  • 运行时异常(RuntimeException)

    • 编写代码时不报错,一运行会报错的异常,是可以预见的异常,如代码的一些逻辑错误等。
    • 可以通过捕捉处理使程序继续执行,是程序自身可以处理的异常,也称为非致命性异常类。
    • 编译时可以被忽略
  • 错误(Error)

    • Error不是异常!它是由虚拟机生成并抛出的。
    • Error及其子类描述Java运行系统中的内部错误以及资源耗尽的错误
    • Error是灾难性的致命的错误,是脱离程序员控制的问题,这类的大多数错误与代码编写者执行的操作无关。
    • 当出现Error时,JVM一般会选择终止线程。
    • 常见的Error如栈溢出等,即使编译也检查不到。
  • 注:Exception和Error的区别

    • Exception可以通过程序自身捕捉处理,而Error是程序自身无法处理的。

三、异常体系结构

  • Java把异常当作对象处理

    • 定义了一个基类java.lang.Throwable作为所有异常的超类。
    • 因此,java异常都是Throwable类的实例。
  • 异常体系结构层次

四、异常处理机制(捕捉和处理异常)

  • 代码示例1
public static void main(String[] args){
        int a=1;
        int b=0;

        //捕捉多个异常,多重捕捉,写多个catch,层次从低到高
        //alt+cmd+T
        try {//try监控区域(要捕捉异常的代码块)
            System.out.println(a/b);
        } catch (Exception e) {
            e.printStackTrace();//打印错误的栈信息
        } catch (Error e){
            System.out.println("Error");
        } finally {//处理善后工作,无论如何都会执行。
            System.out.println("finally");
        }
}

上述代码我们可以看到

  1. try至少和一个catch配套
  2. try语句里的代码块就是需要捕捉异常的代码
  3. finally语句是可选的,finally语句内的代码块会执行了再报错。常用于I/O流中关闭文件等,是无论如何都要执行的。
  4. 尽量不要用默认的printStackTrace信息,而是自己去处理异常。
  5. 被类似的代码块包裹的快捷键是 选中要包裹的代码块,alt+cmd+T
  6. 多个异常的捕捉要从小到大,不然会遗漏。
  • 比如如果第一个catch就捕捉Throwable,第二个catch再写Error,会编译不通过。

  • 高层次的Throwable一般放在最后,以免疏漏异常。

  • 代码示例2 -> 主动抛出异常(方法内部)

public class Test{
  
    public void test(int a, int b){
            if(b == 0)
                  throw new ArithmeticException();  //主动抛出异常
    }
}
public static void main(String[] args){
       new  Test.test(1,0);           
}
  • 原本方法中没有方法体,什么也不输出。但经过主动抛出后,会输出异常信息。

  • 当我们知道有些情况会导致异常时,可以主动抛出异常。比如示例中除数为0必会报错。

  • 代码示例3
    //如果在方法中,处理不了异常,就需要在方法上抛出异常。

public class Test{
    //假如处理不了异常,将异常抛出给方法调用者
    public void test(int a, int b) throws ArithmeticException{
            if(b == 0){
            throw new ArithmeticException();
    }
}
public static void main(String[] args){
         //主函数里调用test方法,并给出异常的处理方法。
        try{
                new Test().test(1,0);      
            }catch(ArithmeticException e){
                 e.printStackTrace();
            }
}

从上述代码我们可以看到

  1. 在方法定义时把可预见的异常抛出给了方法调用者
  2. 方法调用者给出处理异常的方法

五、throw和throws的异同点

  1. 二者出现位置不一样
  • throw语句总是出现在方法体里面,用来抛出一个异常,表示在这个地方就有一个异常出现,程序会在throw后面立即终止,它后面的语句将执行不到。
  • throws是出现在方法名的后面,表示当前方法不处理异常,交给方法调用者处理。
  1. throw只能抛出一个异常,throws可以用逗号分隔抛出多个异常
  2. throw抛出异常时可以不生命或不捕获,而throws抛出异常时,调用他的方法需要声明异常或用try-catch捕获异常。

五、自定义异常

posted @ 2021-09-14 16:43  全辣柯基  阅读(153)  评论(0编辑  收藏  举报