Java异常处理

2021-04-20 11:38:02
## 什么是异常处理 异常本质上是程序上的错误,包括程序逻辑错误和系统错误。比如使用空的引用、数组下标越界、内存溢出错误等,这些都是意外的情况。因此,如何对运行期间出现的错误进行处理和补救呢?Java提供了异常机制来进行处理,通过异常机制来处理程序运行期间出现的错误。 ## 异常体系架构 在Java中异常被当做对象来处理,根类是java.lang.Throwable类,所有异常类都继承于它,异常类分为两大类:Error和Exception。 - Error错误:错误不是异常,而是脱离程序员控制的问题,错误代码通常被忽略,例如:当栈溢出的时候,一个错误就发生了,他们在编译的时候也是检查不到的。 - Exception异常 - 运行时异常(间接或直接继承RuntimeException):这些异常通常时程序的逻辑出现了错误,当出现此类异常时,应该分析程序的逻辑是否正确。 - 检查时异常(不间接或不直接继承RuntimeException):这类异常,是程序必须进行处理的异常,否则不能被编译,即需要显示处理。 >总结 Error 与Exception的区别:异常Exception能被程序本身处理,错误Error是无法处理的 #### java异常体系图 ![javaException.jpg](https://static.daimaku.net/post/202104/20/efc54dd91036c3c6db5510c1b02db719.jpg) ## Java中如何处理异常 java中处理异常分为两种,一种是`抛出异常`,另一种是`捕获异常`,其中有五个关键字,需要大家去了解一下,`try`、`catch`、`finally`、`throw`、`throws` ### 捕获异常 当你发现有段代码有不可控的因素在里面的时候,就可以运用到捕获异常,如下代码 ```java public class App { public static void main(String[] args) { int a = 1; int b = 0; // 有异常的代码 try{ System.out.println(a/b); // 1/0会报错 }catch(ArithmeticException e ){ // catch 中写上 异常的类型 // 捕获异常后 处理的操作 比如打印一句话 System.out.println("分母不能为0"); }finally{ // 无论是否存在异常,代码都会执行到finally,可以不写 System.out.println("方法执行完毕~"); } } } ``` 注意catch中的异常类型 ,首先试试以下代码 ```java public class App { public static void main(String[] args) { // 有异常的代码 try { // 会出现递归的错误 new App().a(); } catch (ArithmeticException e) { // catch 中写上 异常的类型 // 捕获异常后 处理的操作 比如打印一句话 System.out.println("出现异常!"); } finally { // 无论是否存在异常,代码都会执行到finally,可以不写 System.out.println("方法执行完毕~"); } } public void a() { b(); // a中调用b方法 } public void b() { a(); // b中调用a方法 } } ``` 你会发现,catch中并没有捕获异常,因为这个错误类型,它是`ERROR`不属于这个异常类型之中,我们可以尝试换成异常的根类`Throwable`试试看能不能捕获到异常信息把? ```java public class App { public static void main(String[] args) { // 有异常的代码 try { // 会出现递归的错误 new App().a(); } catch (Throwable e) { // catch 中写上 异常的类型 // 捕获异常后 处理的操作 比如打印一句话 System.out.println("出现异常!"); } finally { // 无论是否存在异常,代码都会执行到finally,可以不写 System.out.println("方法执行完毕~"); } } public void a() { b(); // a中调用b方法 } public void b() { a(); // b中调用a方法 } } ``` 运行结果成功捕获异常 java 中还提供了捕获多个异常 ```java public class App { public static void main(String[] args) { int a = 1; int b = 0; // 有异常的代码 try { System.out.println(a / b); // 1/0会报错 } catch (Error e) { System.out.println("Error"); } catch (Exception e) { System.out.println("Exception"); } catch (Throwable e) { // 父类放到下面子类下面,包含关系,从小到大 System.out.println("Throwable"); } finally { System.out.println("方法执行完毕~"); } } } ``` ### 抛出异常 抛出异常一般是写在方法上,如下代码 ```java public class App { public static void main(String[] args) { int a = 1; int b = 0; // 调用test方法 new App().test(1, 0); } public void test(int a, int b) { if (b == 0) { throw new ArithmeticException(); // 主动抛出异常,一般在方法中使用 } } } ``` 运行代码,你会发现代码就会在执行到`throw new ArithmeticException` 那一刻中断 如果我们想让代码抛出异常之后继续执行,该如何操作呢? ```java public class App { // 在方法后面加上 throws + 异常对象的类型 (ArithmeticException、Excetion 、Throwable) public void test(int a, int b) throws ArithmeticException { if (b == 0) { throw new ArithmeticException(); // 主动抛出异常,一般在方法中使用 } } public static void main(String[] args) { // 在调用方法的地方捕获异常 try { new App().test(1, 0); } catch (ArithmeticException e) { // 可以写一些处理异常的代码 System.out.println("出现异常错误~"); } // 代码会继续往下执行 System.out.println("继续执行代码"); } } ``` ### 自定义异常 用户可以自定义异常类,只需要继承Exception类即可,一般情况下用的不多。 新建一个异常类`XueBaException` ```java public class XueBaException extends Exception { private int detail ; //声明一个变量 // 构造器 public XueBaException(int a){ this.detail = a ; } @Override public String toString() { return "XueBaException{" + "detail=" + detail + '}'; } } ``` 写一个测试方法调用`XueBaException`异常类 ```java public class App { // 在方法后面加上 throws + 异常对象的类型 (ArithmeticException、Excetion 、Throwable) public void test(int a) throws XueBaException { if (a > 10) { throw new XueBaException(a); // 主动抛出异常,一般在方法中使用 } } public static void main(String[] args) { // 捕获异常 try { new App().test(11); } catch (XueBaException e) { System.out.println(e); } } } ```