异常
1 异常
1.1 Throwable体系:
- Error
- Exception
注:Throwable、Exception以及RuntimeException都是类
Exception则是可以被抛出的基本类型,我们需要主要关心的也是这个类。
1.2 Exception的分类
- 已检查异常 Exception 必须要处理
- FileNotFoundException
- IOException
- ClassNotFoundException……
- 未检查异常(运行时异常) RuntimeException:程序失误,程序员马虎
- IndexOutOfBoundsException
- ClassCastException
- NullPointerException
- ConcurrentModificationException ……
1.3 处理异常
自行处理:try - catch
1. try-catch必须同时存在
2. 一个try可以有多个catch,但是只有一个catch可能会被执行
3. catch的顺序:
多个异常之间没有关系,顺序随意;
多个异常之间存在父子类关系,则子类异常在前,父类在后
4. e.printStackTrace() 打印异常信息
5. 出现异常的位置后续try部分的代码执行不到了,但不影响catch以及后续代码执行
6. finally 选择性添加 通常用来释放资源 不可单独使用
7. catch可以抓取任意的运行时异常,但不可以随意抓取已检查异常
向上级抛出:throw(方法声明 )
8.当只有在try或者catch中调用退出JVM的相关方法,此时finally才不会执行,否则finally永远会执行
1.4 try - catch - finally
问题:在try中遇到return后,finally会不会执行?
如果执行,在return之前还是之后?
答:try遇到return之后finally会执行,先运行try中的return,得到的结果保存在缓冲区中,之后运行finally中的return,如果不对值进行运算则finally中的return得到的结果将会覆盖点原先try中return得到的结果。 finally中的return不会影响try中的return运行。
代码示例如下:
示例1:
public class ExceptionDemo05 {
public static void main(String[] args){
System.out.println(ExceptionDemo());
}
static int ExceptionDemo(){
int i = 0;
try {
return i++;//i = 1
}catch (NullPointerException e){
e.printStackTrace();
}finally {
return ++i;//i = 2
}
}
}
运行结果:
2
示例2:
public class ExceptionDemo05 {
public static void main(String[] args){
System.out.println(ExceptionDemo());
}
static boolean ExceptionDemo(){
try {
return true;
}catch (NullPointerException e){
e.printStackTrace();
}finally {
return false;
}
}
}
运行结果:
false
throw:接异常对象,取代return
throw new xxException();
需要在方法声明上添加 throws xxException
这个方法的调用者依然需要处理这个异常(try,throws)
最终如果异常到主方法抛出,JVM只能做中断处理
1.5 处理异常的原则:
1. 能自己处理的自己处理
2. 不能处理了再向上抛出
1.6 自定义异常
自定义一个业务逻辑异常:RegisterException。一个注册异常类。
异常类如何定义:
- 自定义一个编译期异常:自定义类,并继承于java.lang.Exception
- 自定义一个运行时期的异常类,自定义类,并继承于java.lang.RuntimeException
1.7 补充:
- 多个异常一次捕获多次处理,格式如下:
try{
编写可能会出现异常的代码
}catch(异常类型A e){
当try中出现A类型异常,就用该catch来捕获,处理异常的代码
//记录日志/打印异常信息/继续抛出异常
}catch(异常类型B e){
当try中出现B类型异常,就用该catch来捕获,处理异常的代码
//记录日志/打印异常信息/继续抛出异常
}
注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常关系,那么子类异常要求在上面catch处理,父类异常在下面catch处理
- 运行时异常被抛出可以不处理,即不捕获也不声明抛出。
- 如果finally有return语句,永远返回finally中的结果,避免该情况出现
- 如果父类抛出多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常
- 父类方法没有抛出异常,子类重写父类该方法时也不可能抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出