Java 异常处理详解 - 教程
目录
一、什么是异常
在Java程序运行过程中,如果出现了不正常的现象,阻止了程序的正常执行,我们称之为异常
但是!
语法错误、逻辑错误 不属于异常的范畴。
异常的本质是一种对对象用来描述程序中出现的问题
Java的异常体系结构
在Java中 ,所有的异常都有一个共同的祖先----java.lang包中的Throwable类。
Throwable类中有两个重要的子类Error和Exception类
Error类表示仅仅依靠程序无法处理的严重错误,比如内存溢出或者虚拟机报错等;发生这些问题的时候,程序员应该尽快让程序安全退出。
Exception类是由Java应用程序抛出和处理的非严重错误,比如所需文件没有找到,作除数,发生这些问题时,可以使用catch和throws来进行处理
Exception又分为两大类
1.运行时异常:运行时异常在编译时不强制要求处理,如数组越界,0作除数等情况
2.检查异常: 必须进行处理,否则编译无法成功,如ClassNotFoundException,IOException
二、if-else与异常处理对比
if-else堵漏洞的方式
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数:");
if(sc.hasNextInt()){
int num1 = sc.nextInt();
System.out.println("请输入第二个数:");
if(sc.hasNextInt()){
int num2 = sc.nextInt();
if(num2 == 0){
System.out.println("对不起,除数不能为0");
}else{
System.out.println("商:" + num1/num2);
}
}else{
System.out.println("输入的不是 int 类型!");
}
}else{
System.out.println("输入的不是 int 类型!");
}
缺点:
1.代码臃肿,业务逻辑和处理错错误混合在一起
2.可读性差
3.难以维护,无法覆盖所有的情况
三、try-catch-finally
使用try-catch可以优雅的处理异常,让业务逻辑更清晰
try{
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数:");
int num1 = sc.nextInt();
System.out.println("请输入第二个数:");
int num2 = sc.nextInt();
System.out.println("商:" + num1/num2);
}catch(ArithmeticException ex){
System.out.println("对不起,除数不能为0");
}catch(InputMismatchException ex){
System.out.println("输入的不是 int 类型!");
}catch(Exception ex){
System.out.println("程序出现未知异常");
}finally {
System.out.println("----谢谢你使用计算器----");
}
特点:
1.多个catch按顺序匹配,先写子类异常,再写父类异常
2.从jdk1.7开始,可以用|合并多个异常:
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); }
3.finally块一定会执行,常用于资源释放
四、throw与throws
throw:在方法的内部,手动抛出异常对象
throws:在方法声明处,声明该方法可能抛出的异常类型
public static void divide() throws Exception {
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
int num2 = sc.nextInt();
if(num2 == 0){
throw new Exception("除数不能为0"); // 手动抛出
}
System.out.println("商:" + num1/num2);
}
调用者:
public static void main(String[] args) {
try {
divide();
} catch (Exception e) {
e.printStackTrace();
}
}
五、自定义异常
除了JDK提供的异常类型,还可以根据业务需要自定义异常
public class MyException extends RuntimeException {
public MyException(String msg){
super(msg);
}
}
特点:
继承RuntimeException------调用的地方不强制处理
继承Exception----属于检查异常,调用的地方必须进行处理
五、总结
1.if-else能做基础校验,但是容易导致代码臃肿,哲凝不是我们想要的
2.try-catch-finally是Java处理异常的标准方式
3.throw 用于制造异常
4.throws用于声明异常
5.运行时异常/检查异常:前者编译不强制,后者必须处理
6.自定义异常:能更好地表达业务语义