Java异常

什么是异常

实际工作中,遇到的情况不可能是非常完美的,比如:你写某个模块时,用户输入不一定符合要求,重新打开某个文件,这个文件可能不存在或文件格式不对等等

软件程序在运行过程中,非常可能遇到刚刚提到的这些情况,我们称之为异常,异常是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。

Java异常的简单分类

检查性异常:最具代表的检查性异常是用户错误或问题导致的异常,这是程序员无法预见的。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。

运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。

错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译时被忽略。例如,虚拟机错误(Virtual MachineError),信号错误(SignalError),链接错误(LinkageError)。

异常体系结构

Java把异常当作对象来处理,并定义了一个基类java.lang.Throwable作为所有异常的超类。
Java异常主要分为Error和Exception,其中Error是程序无法处理的错误,比如OutOfMemoryError、ThreadDeath等,这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;

Exception是程序本身可以处理的异常,这种异常分两大类运行时异常和非运行时异常。程序中应当尽可能去处理这些异常。

运行时异常:ArithmeticException、IllegalArgumentException、ArrayIndexOutOfBoundsException、NullPointerException、ClassCastException等。

非运行时异常:IOException、SQLException等。

异常处理机制

Java的异常处理机制包括:抛出异常、捕获异常和处理异常。
其中涉及到的关键字有:try、catch、finally、throw、throws等

try/catch语句

try/catch语句允许我们测试代码的某一段并捕获可能发生的异常。try/catch语句如下格式:

try {
   // 程序代码
} catch (ExceptionType1 e1) {
   // 处理ExceptionType1异常的代码
} catch (ExceptionType2 e2) {
   // 处理ExceptionType2异常的代码
} catch (ExceptionType3 e3) {
   // 处理ExceptionType3异常的代码
}

throw语句

我们可以在程序中使用throw关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
throw语句用在方法内,用来抛出一个异常,将控制权交给调用者来处理。

    public static void main(String[] args) {
        try {
            int ret = divide(100,0);
        }catch (ArithmeticException e){
            System.out.println("发生了除0异常");
        }finally {
            System.out.println("处理完了异常");
        }
    }

    public static int divide(int a,int b){
        if(b == 0){
            throw new ArithmeticException();
        }else{
            return a / b;
        }

    }

throws语句

throws语句用在方法声明后面,用来声明方法可能抛出的异常类型。

public returnType methodName() throws ExceptionType {
   // 程序代码
}

finally语句

finally语句用来执行所有的清除工作,无论是否发生了异常。比如:在finally语句中关闭已打开的连接和流。

try {
   // 程序代码
} catch (ExceptionType1 e1) {
   // 处理ExceptionType1异常的代码
} catch (ExceptionType2 e2) {
   // 处理ExceptionType2异常的代码
} finally {
   // 无论如何都会执行的代码
}

自定义异常

在Java中你可以自定义异常。编写自己的异常类时需要记住的一点是,它们必须继承自Exception类或是它的子类。

class MyException extends Exception {
   private int detail;
   MyException(int a) {
      this.detail = a;
   }
   public String toString() {
      return "MyException[" + detail + "]";
   }
}

实际应用中的经验总结

  • 处理运行时异常时,采用逻辑去合理规避同时辅助以try-catch进行预防处理。
  • 在多重catch块后面,加上一个catch(Exception e)来处理可能被遗漏的异常。
  • 对于不可控的第三方代码,考虑使用try-catch进行包装。
  • 尽量去处理异常,切忌只是简单地调用e.printStackTrace(),这样对于真正排查问题来说,没有太大的帮助。
  • 尽量添加finally语句块,进行一些资源清理的收尾工作。
  • 合理设计自定义异常,明确异常场景,从而方便别人理解和阅读你写的代码。

笔记总结于视频:https://www.bilibili.com/video/BV12J41137hu?spm_id_from=333.788.videopod.episodes&vd_source=16bf0c507e4a78c3ca31a05dff1bee4e&p=77

你可能感兴趣的:(java,开发语言)