异常机制
什么是异常
-
异常(Exception):指程序运行过程中的各种紧急情况,如文件找不到、网络连接失败、非法参数等
-
程序运行过程中出现异常,影响程序的正常执行过程
-
异常简单分类:
-
检查异常:最具代表性的检查异常是由用户错误或问题引起的,这是程序员无法预测的。
例如,当打开不存在的文件时,会出现异常。这些异常在编译过程中不能简单地忽略
-
运行异常:运行异常是程序员可以避免的异常。与检查异常相反,程中可以忽略操作异常
-
错误:错误不是异常的,而是程序员控制的问题。代码中忽略了错误。例如,当堆栈溢出时,会出现错误,在编译过程中无法检查
-
系统结构异常
-
java将异常视为对象并定义基类java.lang.Throeable作为所有异常的超类
-
在Java API许多异常分为两类:错误(error)和异常(Exception)
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-alBXmvb0-1646831736164)(C:\Users\kevin\AppData\Roaming\Typora\typora-user-images\image-20220309170935915.png)]
-
Error
- Error类对象由java虚拟机生成并抛出,大多数错误与代码编写器执行的操作无关
- JVM运行错误(VirtualMachineError);当JVM当没有继续执行所需的内存资源时,就会出现OutOfMemoryError。当这些异常发生时,JVM一般会选择线程终止
- 当虚拟机试图执行应用程序时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是无法检查的,因为它们除了控制和处理应用程序的能力外,而且大多数都是程序运行中不允许的情况
-
Exception
- 在Exception有一个重要的子类分支RuntimeException(异常运行)
- ArrayIndexOutOfBoundsException
- ArithmeticException(算术异常)
- MissingResourceException(资源丢失)
- ClassNotFoundException(找不到类)
- NullPointerException
- 上述异常不检查,可捕获或不处理;这些异常通常是由程序逻辑错误引起的,程序应尽可能避免从逻辑角度产生
- IOException
- 在Exception有一个重要的子类分支RuntimeException(异常运行)
-
Error和Exception区别
- Error当这些异常发生时,通常是灾难性的致命错误,程序无法控制和处理,java虚拟机一般会选择终止线程
- Exception程序通常可以处理,这些异常可以在程序中尽可能处理
java异常处理机制
-
抛出异常,捕获异常
package com.kum.shu.exception; public class Test2 { public static void main(String[] args) { /*//捕获异常快捷键:Ctrl Alt T try { System.out.println(a/b); } catch (Exception e) { System.exit(0); //终止程序 *//*e.printStackTrace(); //打印错误栈信息*//* } finally { }*/ try { new Test2().add(1,0); } catch (ArithmeticException e) { e.printStackTrace(); } } //假设这种方法不能处理这种异常,抛出异常的方法 public void add(int a,int b) throws ArithmeticException{ if(b==0){ //主动抛出异常 throw new ArithmeticException(); } System.out.println(a/b); } }
-
五个关键词处理异常:try、catch、finally、throw、throws
package com.kum.shu.exception; public class Test { public static void main(String[] args) { int a =10; int b = 0; 假设要捕捉异常:从小到大! try { //监控区域 System.out.println(a/b); }catch (ArithmeticException ar){ //捕获异常 System.out.println("ArithmeticException"); } catch (Exception e){ //捕获异常 System.out.println("Exception"); } catch (Error er){ //捕获异常 System.out.println("Error"); } catch (Throwable t){ //捕获异常 System.out.println("Throwable"); } finally { ///处理善后工作:无需 System.out.println("程序错误!请检查!请检查!!"); } System.out.println("=================="); try { //监控区域 new Test().A(); }catch (Error e){ //捕获异常 System.out.println("Error"); }finally { ///处理善后工作:无需 System.out.println("请检查"); } } public void A(){ B(); } public void B(){ A(); } }
自定义异常
-
使用Java内置异常类可以描述编程中的大部分异常情况。此外,用户还可以定制异常。用户只需继承自定义异常类别Exception类即可
-
自定义异常类在程序中使用,一般可分为以下步骤:
- 创建自定义异常类。
- 通过方法throw抛出异常对象的关键字。
- 如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获和处理;否则,在方法的声明中通过throws关键字说明要抛出方法调用者的异常,继续下一步操作。
- 在异常方法的调用者中捕获者。
package com.kum.shu.exception.demo02; //自定义异常类 public class MyException extends Exception{ //传输数大于10,则抛出异常 private int detail; public MyException(int a) { this.detail = a; } //toString:打印信息异常 @Override public String toString() { return "MyException{" "detail=" detail '}'; } } package com.kum.shu.exception.demo02; import java.util.Scanner; public class Test { ublic static void main(String[] args) { try { test(11); } catch (MyException e) { System.out.println("myException"+e); } } static void test(int a) throws MyException { System.out.println("传递的参数为:"+a); if (a>10){ throw new MyException(a); } System.out.println("OK"); } }
总结
- 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
- 在多重catch块后面,可以加一个catch (Exception)来处理可能会被遗漏的异常
- 对于不确定的代码,也可以加上try-catch,处理潜在的异常
- 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源