平时不怎么注意的异常处理

1 简介

       异常就是一种信号,用于向调用者传递信息,表示程序发生的意外情况,例如除数为0,数组超界等等。程序运行时一旦出现异常,将会导致程序立即终止,异常之后的代码将无法继续执行,所以需要对异常进行处理

2 常见的异常

       每一种异常都是用一个类表示的

异常含义发生时机
ArithmeticException算术异常除数为0
ArrayIndexOutOfBoundsException数组下标越界访问下标不存在的数组元素
NullPointerException空指针异常对null调用方法
ClassCastException类型转换异常将两个不相关的类进行强制转换
NumberFormatException数字格式异常字符串不满足数字的格式要求,无法进行转换
ClassNotFoundException找不到类异常指定的类不存在
ParseException解析异常字符串格式不正确

3 异常分类

  • 检查异常:所有继承于Exception类的异常,该类异常是可预期的,很有可能发生。要求编译器显示处理,即打代码时就要求强制处理,简单说就是有时我们调用某个方法,会出现红色下划线提示你要加一个抛出异常的后缀,这就是提前预想到你这样做很有可能出现错误,就强制你先提前做出来来应当可能出现的异常 。例如ClassNotFoundException 、ParseException
    在这里插入图片描述
  • 运行时异常:所有继承于RuntimeException类的异常,该类异常不一定可以预测发生。如果代码没有逻辑错误一般不会出现运行时异常。不要求编译器必须处理该异常,例如你写一个除法,如果没有除数是0这种逻辑错误的话那就是一个正常的除法运算,也没有必要强制处理。例如:ArithmeticException、NullPointerException、ArrayIndexOutOfBoundsException

4 异常的产生

  1. 抛出异常(throw):当程序发生异常时,自动生成一个对应异常类的对象,然后将这个对象提交给JRE
  2. 捕获异常(catch):当JRE接收到异常对象后,寻找能处理此异常的代码,找到之后就把这个异常对象交给它来处理
  3. 如果JRE找不到可以捕获异常的代码,则运行时系统将终止,程序退出,也就是程序崩了,所以需要对异常进行处理

5 异常的处理

5.1 使用try…catch… 处理异常

       使用try…catch… 简单说就是自己发现异常自己解决

try {
	//try中写可能出现异常的代码
}

catch(异常类型 异常对象) { //捕获异常
	/*参数为可能出现的异常类型的对象,不可能出现的异常就不用考虑,
	这个对象就是之前说的JRE接收到的异常对象*/
	//catch中写对异常进行处理的代码
}
finally {
	//无论是否出现异常都要执行的代码,即使之前代码出现return也会执行
}

catch中查看异常信息的方法:

方法作用
异常对象.printStackTrace()打印堆栈中的异常详细信息,该方法使用单独的线程输出,每次出现的位置不固定,实际上是用System.err.println()输出
异常对象.getMessage()获取异常的消息字符串

使用try…catch… 要注意的点:

  • finally如果不需要的话可以省略
  • 只有执行Ssytem.eixt(0)终止当前正在运行的JVM才不会执行finally中的代码
  • try是必须要有的,而catch和finally至少要有一个
  • catch只能捕获参数规定类型的异常,如果有的异常不可能出现就可以不考虑这个类型
  • catch可以有多个,用来捕获多个不同类型异常,并且可能对不同类型的异常进行不同的处理。捕获异常时从第一个catch开始检查,一旦能捕获,之后的catch就不再继续处理。
  • 异常类型为Exception时,就包括了所有的异常类型。写代码时应当将范围小的异常放在前面
  • 如果异常处理相同,那么可以将多个异常处理合并到同一个catch中(multi-catch),格式为:catch(异常类型A | 异常类型B | … | 异常类型N e) ,e仍然是异常对象,但属于什么类型就从前面的几个异常类型中选择

5.2 使用throws声明抛出异常

       如果一个方法中会产生某种异常,但不知道如何处理这种异常,可以声明该方法会抛出异常来表明该方法将不会对这种异常进行处理,而由该方法的调用者来处理

throwsthrow
声明方法中会抛出的异常在方法内手动抛出异常

使用throws声明抛出异常:

在这里插入图片描述
       由于该方法可能会出现异常,可以选择抛出对应类型的异常,然后在调用该方法的地方来处理这个异常,当然如果调用者不进行处理,则会继续向上抛出。如果都不进行处理,最终由JVM处理,JVM的处理方式就是在控制台打印异常信息
       throws也可以抛出多个类型的异常,在throws之后直接加异常类型,用逗号隔开。格式为:
public 返回类型 方法名(参数) throws 异常类型1,异常类型2,… { … }
       可以使用一个范围大的异常来表示多个子异常,但不建议,因为可读性差

使用throw手动抛出异常
       就是创建一个对应类型的异常对象,然后抛出即可,例如
在这里插入图片描述

6 自定义异常

       之前提到的一些异常类型只是一些常见的情况,但是在实际开发中,每个项目的需求不一样,那么就可能出现特别的异常,而这些异常可能是上述的类型中没有的,所以需要自定义。所谓的自定义异常就是自定义异常类。使用方法和上述的抛出异常方法一样
在自定义异常类时,需要继承Exception类或其他子类。一般多继承Exception(检查异常)或RuntimeException(运行时异常),一般可以使用父类的构造方法
在这里插入图片描述

7 方法重写的异常问题

  • 若父类没有抛出异常,子类不能抛出检查异常,但是可以用try…catch处理或可以抛出运行时异常
  • 相反的,如果父类抛出异常,子类可以不抛出异常
  • 重写的方法不能抛出比父类方法抛出异常范围更大的异常

8 异常的定位和解决

  1. 首先看控制台报错信息有没有Casued by,如果有则从Caused by开始找,如果没有则从头开始找
  2. 找到第一行自己写的代码,问题就在那里,因为之后的报错位置只是很多层的调用者
  3. 根据找到的位置看异常类型和异常消息,确定产生异常的原因
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值