在程序编写中,难免会产生异常,这时候就需要对异常进行处理
异常
异常的体系
Throwable
Error
- 通常出现重大问题如:运行的类不存在或者内存溢出等
- 不编写针对代码对其处理
Exception
- 在运行时运行出现的一起情况,可以通过try catch finally
Exception和Error的子类名都是以父类名作为后缀
Throwable中的方法
-
getMessage()
获取异常信息,返回字符串 -
toString()
获取异常类名和异常信息,返回字符串 -
printStackTrace()
获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void -
printStackTrace(PrintStream s)
通常用该方法将异常内容保存在日志文件中,以便查阅
throws和throw
-
throws用于标识函数暴露出的异常
-
throw用于抛出异常对象
-
throws与throw的区别:
- thorws用在函数上,后面跟异常类名
- throw用在函数内,后面跟异常对象
异常处理
try {
需要检测的代码;
} catch(异常类 变量){
异常处理代码;
} finally {
一定会执行的代码;
}
try {
//需要检测的代码;
} catch(Exception e){
//异常处理代码;
}
try {
//需要检测的代码;
} finally{
//一定会执行的代码;
}
Finally
代码块只有一种情况不会被执行。就是在之前执行了System.exit(0)
自定义异常
自定义类继承Exception或者其子类
通过构造函数定义异常信息
例:
Class DemoException extends Exception {
DemoException(String message) {
super(message);
}
}
通过throw将自定义异常抛出
throw new DemoException();
异常在子父类覆盖中的体现
- 子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类
- 如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集
- 如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常,如果子类方法发生了异常。就必须要进行try处理。绝对不能抛.
异常的好处
- 将问题进行封装。
- 将正常流程代码和问题处理代码相分离,方便于阅读。
异常的处理原则
1,处理方式有两种:try 或者 throws。
2,调用到抛出异常的功能时,抛出几个,就处理几个。
一个try对应多个catch。
3,多个catch,父类的catch放到最下面。
4,catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句。也不要不写。
当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。
try{
throw new AException();
} catch (AException e) {
throw e;
}
如果该异常处理不了,但并不属于该功能出现的异常。
可以将异常转换后,在抛出和该功能相关的异常。
或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,
当调用者知道。并处理。也可以将捕获异常处理后,转换新的异常。
try {
throw new AException();
} catch (AException e) {
// 对AException处理。
throw new BException();
}
异常的注意事项:
在子父类覆盖时:
- 子类抛出的异常必须是父类的异常的子类或者子集
- 如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛
异常细节
- RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明
- 一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类
- 如果父类抛出多个异常,那么重写(覆盖)方法必须抛出那些异常的一个子集,不能抛出新的异常
- 介绍异常在分层设计时的层内封装
- finally中的代码无论如何都会执行,通常用于关闭资源
- catch是用于处理异常。如果没有catch就代表异常没有被处理过,如果该异常是检测时异常。那么必须声明
RuntimeException
Exceptoin中有一个特殊的子类异常RuntimeException运行时异常
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过
如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过
之所以不用在函数声明,是因为不需要让调用者处理
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正
自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException
对于异常分两种:
- 编译时被检测的异常
- 编译时不被检测的异常(运行时异常。RuntimeException以及其子类)