# 异常抛出及自定义异常
# Java中的异常抛出
throw 将产生的异常抛出(动作)
throws 声明将要抛出何种类型的异常(声明)
public void 方法名(参数列表) throws 异常列表 {
// 调用会抛出异常的方法或者:
throw new Exception();
}
1
2
3
4
2
3
4
例子:声明抛出一个异常
public void divide(int one, int two) trhows Exception {
if (two == 0) {
throw new Exception("两数相除,除数不能为0");
} else {
System.out.println("两数相除,结果为:" + one / two);
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
处理1:使用try-catch处理
public void compute () {
// do something
try {
divide(5, 0);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
处理2:(或)继续抛出异常,让其他更上一层调用程序去处理
public void compute() throws Exception {
// do something
divide(5, 0);
}
1
2
3
4
2
3
4
# 自定义异常
class 自定义异常类 extends 异常类型 {
// do something
}
1
2
3
2
3
例子
package com.test
public class DrunkException extends Exception {
// 自定义一个有参的构造器
public DrunkException(String message) {
super(message);
}
// 因为自定义了构造器,所以编译器不会为我们自动创建一个无参构造器
// 但,有时候我们需要用到无参的构造器,所以再添加一个无参构造器
public DrunkException() {
// ...
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# Java中的异常链
异常链功能实现,两种实现方法:
package com.test
public class ChainTest {
/**
* test1():抛出"喝大了"异常
* test2():调用test1(),捕获"喝大了"异常,并且包装成运行时异常,继续抛出
* main方法中,调用test2(),尝试捕获test2()方法抛出的异常
*/
public static void main(String[] args) {
ChainTest ct = new ChainTest();
try {
ct.test2();
} catch (Exception e) {
e.printStack();
}
}
public void test1 () throws DrunkException {
throw new DrunkException("喝酒别开车!");
}
public void test2 () {
try {
test1();
} catch (DrunkException e) {
// 包装成运行时异常
RuntimeException newExc = new RuntimeException("司机一滴酒,亲人两行泪");
newExc.initCause(e);
throw newExc;
}
}
}
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
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
或者
public void test2 () {
try {
test1();
} catch (DrunkException e) {
// 包装成运行时异常
RuntimeException newExc = new RuntimeException(e);
throw newExc;
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
总结
Exception的父类是Throwable
使用try-catch-finally语句捕获并处理异常 :::
可以使用throw语句抛出异常 :::
# 实际应用中的经验与总结
1、处理运行时异常时,采用逻辑去和里规避同时辅助try-catch处理
2、在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
3、对于不确定的代码,也可以加上try-catch,处理潜在的异常
4、尽量去处理异常,切忌只是简单的调用printStackTrace()去打印输出
5、具体如何处理异常,要根据不同的业务需求和异常类型去决定
6、尽量添加finally语句块去释放占用的资源,尤其是在有网络连接或有数据库操作的情况下等等。
# 练习题
要求:
1、定义字符串数组保存图书信息
2、提示用户输入,分别按"书名"和"图书序号"查找图书
3、根据输入信息进行适当的异常处理
a、如果输入类型错误,抛出"错误命令异常",并提示重新输入
b、如果书名不存在,抛出"图书不存在异常",并提示重新输入
c、如果图书序号超过字符串数组范围,抛出"图书不存在异常",并提示重新输入