一、定义
在 Java 中,异常(Exception)是指程序在执行过程中遇到的不正常情况,这些情况可能导致程序无法继续执行或产生错误的结果。异常可以是 Java 标准库中提供的内置异常类,也可以是开发人员自定义的异常类。
二、层次结构
所有的异常都是由Throwable继承而来,但在下一层立即分解为两个分支: Error和Exception。
- Error类层次结构描述了Java运行时系统的内部错误和资源耗尽错误。应用程序不应该抛出这种类型的对象。如果出现了这样的内部错误,除了通告给用户,并尽力使程序安全地终止之外,再也无能为力了。这种情况很少出现。
- 在设计Java程序时,需要关注Exception层次结构。这个层次结构又分解为两个分支:一个分支派生于RuntimeException;另一个分支包含其他异常。划分两个分支的规则是:由程序错误导致的异常属于RuntimeException,例如:空指针、除数为0等,我们要做的就是解决代码问题;而程序本身没有问题,但由于像I/O错误这类问题导致的异常属于其他异常,我们用try catch解决。
三、异常的抛出
在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者。具体语法如下:throw new XXXException("自定义提示信息");
需要注意的是:
- throw必须在方法体内部;
- 异常抛出后,之后的代码就不再执行;
- 抛出的对象必须是Exception或其子类对象;
四、异常的解决
1、异常声明throws
当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。语法为:
修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2{}
eg:
public static void divide(int a, int b) throws ArithmeticException {if (b == 0) {throw new ArithmeticException("除数不能为0");}int result = a / b;System.out.println("结果:" + result);
}
2、异常的捕获
要想捕获一个异常,必须设置try/catch语句块。由于throws对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理。如果真正要对异常进行处理,就需要try-catch。语法为:
try {// 可能抛出异常的代码
} catch (ExceptionType1 e1) {// 处理异常类型1的情况
} catch (ExceptionType2 e2) {// 处理异常类型2的情况
} finally {// 可选的finally语句块,用于执行清理操作
}
finally语句块:不管是否有异常被捕获,finally子句中的代码都被执行。以下情况会执行finally中的代码:
- try代码没有抛出异常。在这种情况下,程序首先执行try语句块中的全部代码,然后执行finally子句中的代码。随后,继续执行try语句块之后的第一条语句。
- 抛出一个在catch子句中捕获的异常。在这种情况下,程序将执行try语句块中的所有代码,直到发生异常为止。此时,将跳过try语句块中的剩余代码,转去执行与该异常匹配的catch子句中的代码,最后执行finally 子句中的代码。如果catch子句没有抛出异常,程序将执行try语句块之后的第一条语句。如果catch子句抛出了一个异常,异常将被抛回这个方法的调用者。
- 代码抛出了一个异常,但这个异常不是由catch子句捕获的。在这种情况下,程序将执行try语句块中的所有语句,直到有异常被抛出为止。此时,将跳过try语句块中的剩余代码,然后执行finally子句中的语句,并将异常抛给这个方法的调用者。
五、自定义异常
自定义异常是指由开发人员根据实际需求创建的异常类,它们扩展自Java标准库中的Exception或其子类。与标准异常类不同,自定义异常类可以提供更具体的异常信息、更详细的上下文信息,以及针对特定业务逻辑的错误处理逻辑。
创建一个自定义异常类,方式如下:
1. 自定义异常类,然后继承自Exception 或者 RunTimeException
2. 实现一个带有String类型参数的构造方法,参数含义:出现异常的原因
案例:
class MyCustomException extends Exception{//无参构造方法public MyCustomException(){// 调用父类的构造方法super();}public MyCustomException(String msg){// 调用父类的构造方法,并传递错误信息super(msg);}
}
public class Main {public static void main(String[] args){try{// 模拟一个场景,需要抛出自定义异常throw new MyCustomException("这是一个自定义异常");}catch(MyCustomException e){// 捕获并处理自定义异常System.err.println("捕获到自定义异常:" + e.getMessage());}}
}
输出结果为: