异常处理

异常概述与异常体系结构

Throwable:所有异常都继承于Throwable,分为Exception和Error。
Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。
比如 :StackOverflowError栈内存溢出和OutOfMemory堆内存溢出。一般不编写针对性的代码进行处理。
Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。
例如:空指针访问,试图读取不存在的文件,网络连接中断,数组角标越界。
异常分类:
编译时异常,CheckException及它的子类,例如IOException,FileNotFoundexception,SQLException等;
运行时异常,RuntimeException类及它的子类,例如NullPointerException,ClassCastException,IndexOutOfBoundException等。

异常处理机制一

异常的处理:抓抛模型
抛出异常:程序在正常执行的过程中,如果出现异常,就会生成一个异常类的对象,并将此对象提交给java运行时系统。
捕获异常:如果一个方法抛出异常,该异常就会抛出给调用者方法中处理。如果异常没有在调用者方法中处理,继续抛给上层方法,直到异常被处理

1
2
3
4
5
6
7
8
9
10
11
12
try{
// 可能出现异常的代码
}catch(异常类型1 变量名1){
// 处理异常的方式1
}catch(异常类型2 变量名2){
// 处理异常的方式2
}
...
finally{
// 不论在try代码块中是否发生了异常事件,catch语句是否执行,是否有异常,是否有return,
// finally块中的语句都会被执行。
}

( I ) try 代码块:监视代码执行过程

旦发现异常则直接跳转至 catch ,如果没有 catch ,则直接跳转至 finally

( 2 ) catch 代码块:可选执行的代码块,如果没有任何异常发生则不会执行,如果发现异常则进行处理或向上抛出。这一切都在 catch 代码块中执行。

( 3 ) finally 代码块:必选执行的代码块,不 管是否有异常产 生,即使发生OOM也会执行,通常用于处理善后清理工作。如果 finally 代码块没有执行,那么有三种可能:

  • 没有进入try 代码块。

  • 进入try代码块,但是代码运行中出现了死循环或死锁状态。

  • 进入 try 代码块,但是执行了System.exit()操作。

注意, finally 是在 return 表达式运行后执行的,此时将要return 的结果已经被暂存起来,finally 代码块执行结束后再将之前暂存的结果返回。

1
2
3
4
5
6
7
8
9
public static int finallyNotWork () { 
int temp = 10000 ;
try {
throw new Exception ();
} catch (Exception e ) {
return ++temp ;
}finally{
temp = 99999;
}

此方法的结果返回10001,而不是99999!
不要在finally 代码块中使用 return 语句,否则会覆盖掉 try 或 catch 代码块中return的结果。

异常处理机制二

throws + 异常类型
1.写在方法的声明处,指明可能抛出的异常类型。一旦方法体执行出现异常时,就会将生成的异常类对象抛给调用者。异常代码后续的代码不再执行。
2.只是将异常抛给了调用者,并没有将异常处理掉

手动抛出异常

throw + new Exception(“提示信息”),必须在方法声明时用throws出指明可能抛出的异常。
throw : 生成一个异常对象。声明在方法体内。
throws : 处理异常。声明在方法的声明处。

用户自定义异常类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
* @Description 用户自定义异常类MyException,用于描述数据取值范围错误信息。
* 用户自己的异常类必须继承现有的异常类。
* @author sweetboyZhang
* @date 2020年2月13日下午3:15:59
*/
public class MyException extends Exception {

static final long serialVersionUID = -703489719074899L;// 序列号
private int id;// 异常种类
public MyException() {

}

public MyException(String msg,int id) {
super(msg);
this.id = id;
}

public int getId() {
return this.id;
}
}

public class MyExceptionTest {
public void regist(int num)throws MyException{
if(num < 0) {
throw new MyException("人为负数,不合理",1);
}
else {
System.out.println("登记人数:"+num);
}
}

public void manager() {
try {
regist(-100);
}catch(MyException e) {
System.out.println("登记错误,出错种类:"+e.getId());
}
System.out.println("本次登记操作结束");
}

public static void main(String[] args) {
MyExceptionTest my1 = new MyExceptionTest();
my1.manager();
}
}