第八章 异常(20210630)
异常定义
程序正在编译或执行时,发生不可预料的问题,不严重可以通过修改代码解决。(拔网线)
异常的继承关系
父类Throwable
- 子类Error
程序正在编译或执行时,发生不可预料的问题,严重到不可以通过修改代码解决(砸碎电脑)。 - 子类Exception
异常的种类
- 未捕获异常:编译可以通过,运行时被JVM抓住报错
RuntimeException及其子类 - 捕获异常:编译时就报错,不能运行,必须处理
除了RuntimeException类的其他异常类
异常的处理机制
1.try catch --可以处理所有异常
语法:
try{
//可能会产生异常的代码块
m=0;
int s = 10/m;
}catch(可能发生异常的类名 对象名){
//发生异常之后,处理异常的代码块
}
- try中写可能会产生异常的代码块,如果发生异常直接将产生的异常对象以及代码的执行权交给catch代码块。
- 一个try catch 里可以写多个catch,需要按照Exception的继承关系排列(从子到父)。异常发生时,只执行当前对应的catch代码块中的内容,其他的catch都不执行。
try {
int k = new Scanner(System.in).nextInt();
int res = 10/k;
}
catch(Error e) {
}
catch(ArithmeticException e) {//被除数为0异常
}
catch(InputMismatchException e) {//数据类型不匹配异常
}
catch(RuntimeException e) {//父类
}
catch(Exception e) {//父类爸爸
}
catch(Throwable obj) {//父类爷爷
}
2.throws–只能处理捕获异常(编译异常),不能处理未捕获异常(运行异常)
语法:
在发生异常的语句 所在的方法定义形参列表后 加 throws + 抛出的异常类名
public static void main(String[] args) throws IOException{
System.out.println("请输入");
int m = System.in.read();//IOException 捕获异常
}
- 处理原理:将异常扔给上级主调方法,直到JVM
- throws后也可写多个异常类名,但也要按照继承关系 从子到父。
finally关键字
由于一旦发生异常,异常后的代码将无法执行,但有些代码我希望它即使发生异常也要执行,那么就把这些代码写到finally中。
- 一个try只能跟一个finally。
原因:第一个finally后的代码就不会被执行到 - finally的代码原则上在最后执行,但try-catch代码块中有return时,先执行finally代码,再执行return。
原因:return后的代码不被执行
public static void main(String[] args) {
int x =new TestFinallyAndReturn().test();//间接调用
System.out.println(x);
}
int test() {
try {
System.out.println("请输入一个除数try:");
int k = new Scanner(System.in).nextInt();
int res = 10/k;
return res;
}
catch(Exception e) {
System.out.println("catch");
return 0;
}
finally {
System.out.println("finally执行");
}
}
输出结果:
请输入一个除数try:
5
finally执行
2
- 只有在finally之前有System.exit(int)时,finally代码不执行。
原因:System.exit(int)关闭JVM
public static void main(String[] args) {
int x =new TestFinallyAndReturn().test();//间接调用
System.out.println(x);
}
int test() {
try {
System.out.println("请输入一个除数try:");
int k = new Scanner(System.in).nextInt();
int res = 10/k;
System.exit(1);//关闭 JVM java虚拟机
return res;
}
catch(Exception e) {
System.out.println("catch");
return 0;
}
finally {
System.out.println("finally执行");
}
}
输出结果:
请输入一个除数try:
5
throw关键字
抛出异常
1.理解throw
在try-catch中,发生异常时,实际是由JVM创建了一个异常类,并由throw关键字将异常对象抛给相应的catch。此处也可以理解为什么catch语法中括号内写的是“类名 对象名”,可以将其理解为传参。
try {
String s = null;
s.equals("111");
//JVM立刻创建一个异常类的对象 并由throw关键字 将此异常对象抛给对应的catch
//throw new NullPointerException()
int k = 10/0;
//JVM创建ArithmeticException类型对象
//throw new ArithmeticException();
}catch(NullPointerException e) {
}
2.应用:自定义异常
创建父类FireException继承 Exception,让FireException成为异常的子类。
public class FireException extends Exception{
@Override
public String toString() {
return "着火了,拨打119";
}
}
多态,分别定义Big Small 类,继承FireException。
public class BigFireException extends FireException{
@Override
public String toString() {
//此处调用了父类的toString()方法
//好处:当父类toString()方法返回值修改时,子类不必每个都修改。
return super.toString() + "着大火了,快跑,沿着安全通道跑!!!";
}
}
public class SmallFireException extends FireException{
@Override
public String toString() {
return super.toString() + "着的是小火,用灭火器灭火,注意安全!!!";
}
}
public class Boys {
void smoke() throws SmallFireException ,BigFireException{
System.out.println("******************");
System.out.println("请选择您本次丢弃烟头的地点");
System.out.println("1 水桶");
System.out.println("2 柴火垛");
System.out.println("3 鞭炮堆");
System.out.println("******************");
Scanner scan = new Scanner(System.in);
int cmd = scan.nextInt();
switch(cmd) {
case 1:System.out.println("真好,真棒!!!");break;
case 2:throw new SmallFireException();
case 3:throw new BigFireException();
default:System.out.println("您输入不存在");break;
}
}
}
上记代码中,在switch代码块的case2,case3 处,使用throw关键字抛出自定义异常。
public class TestFireException {
public static void main(String[] args) {
// TODO Auto-generated method stub
Boys xiaoMing = new Boys();
try {
xiaoMing.smoke();
}
catch(Throwable e) {
System.out.println(e.toString());
}
// catch(SmallFireException sfe) {
// System.out.println(sfe.toString());
// }
// catch(BigFireException bfe) {
// System.out.println(bfe.toString());
// }
}
}
问:为什么重写Throwable的toString方法而不是自己重新定义一个方法?
答:重写toString()方法时,在捕捉异常时,可以只写一个catch Throwable异常,异常对象可以调用toString()方法。但是,如果在子类BigFireException(SmallFireException)中重新定义一个方法,无法通过Throwable 的异常对象调用该子类自己的方法。
错误信息:The method toStringzidingyi() is undefined for the type Throwable
上一篇: redis:详解
下一篇: C# 关于数组的几个方法
推荐阅读
-
node.js express捕获全局异常的三种方法实例分析
-
ZendFramework框架下,在ErrorController抓住异常之前就报错(连接数过多?),该怎么获取并处理此类异常信息
-
99%的程序都没有考虑的网络异常
-
mysql_query()函数异常问题
-
关于curl时提示“ couldn't connect to host ”的异常信息
-
php 错误处理与异常处理方法与实例教程
-
Mysql异常:Every derived table must have its own alias
-
mysql字符串的隐式转换导致查询异常的问题_MySQL
-
php写XML文件编码异常,求解答
-
php更新mysql后获取影响的行数发生异常解决方法_PHP