先对异常做个整体描述,便于对异常有个了解,从而更好地理解细节。
异常的优势:
最根本的优势就是将检测错误(由调用的方法完成)从处理错误(调用方法)中分离出来:
也就是说,在编写程序时,有可能发生异常的地方,我们不作处理,而是抛出去,谁调用这个方法,谁去处理。
(如果在发生异常的地方去处理,程序会比较乱,不方便看整体流程,即阅读性不太好,抛出异常,增加了阅读性)
异常的两大类:
编译时异常:这种类型异常,如果出错,编译不能通过,用命令窗口编译,则在第一步javac命令后,就会出现异常;
如果用高级工具,如MyEclipse,在写程序是,行的开头就出现红色叉号,意识是这是语法错误。
运行时异常(RuntimeException):
这类异常,在编译时可以通过,就算没有处理也可以通过,所以也叫免检异常(可以理解为在编译阶段不检查这类错误)
这类异常java语法正确,但是因为程序员的粗心或逻辑发生错误,如除数为零(这个是数学里的语法错误),数组下标越界等等。
这类异常一般不处理,因为如果处理了,那么这些错误就隐藏了,而这些错误我们是希望修改代码的。
|— 类 Throwable
|—Exception
|— RuntimeException
|— IndexOutOfBoundsException
|— IllegalArgumentException
|— NullPointerException
|— 等等
|— ClassNotFoundException
|— NoSuchMethodException
|— IOException
|— 等等
|— Error
|— ThreadDeath
|— 等等
免检异常包括 RuntimeException和Error
异常处理两种方式:
1、捕获异常:try catch
格式1 try{
//可能抛出异常的代码
} catch(异常类 对象){
//处理该异常类型的语句
}
finally {
//一定会执行的代码
//只有catch块使用System.exit(1);程序退出。执行不到finally语句
}
格式2 try{
//可能抛出异常的代码
} catch(异常类 对象){
//处理该异常类型的语句
}
格式3
try{
//可能抛出异常的代码
}
finally {
//一定会执行的代码
//只有catch块使用System.exit(1);程序退出。执行不到finally语句
}
2、声明异常:throws (如果声明了异常,那么调用者一定得处理,必须在try...catch和throws直接二选一,如果处理选try...catch,如果不处理,抛给调用者处理)
格式:public void 方法名() throws 异常1,异常2,异常3,...{ 方法体}
1 声明异常时尽可能声明具体异常类型,方便更好的处理;
2 方法声明几个异常就对应有几个catch块;
若多个catch块中的异常出现继承关系,父类异常catch块放在最后;即小范围的异常必须放在大范围异常之前。
3 在catch语句块使用Exception类作为异常类型时:
所有子类实例都可以使用父类接收(向上转型),即所有的异常对象都可以使用Exception接收;
throwable,throws与throw的区别:
throwable: 是异常类的基类。
thorws: 用在方法上,后面跟异常类名,可以是多个异常类。(如果声明了异常,那么调用者一定得处理,必须在try...catch和throws直接二选一,如果处理选
try...catch,如果不处理,抛给调用者处理)
throw: 用在方法内,后面跟异常对象,只能是一个。手动抛出异常(自定义异常)(如果函数内throw了异常,要么try...catch,要么声明throws)