异常:Java中出现的不正常情况,就是异常
以下情况不算是异常:
-
编译的语法错误
-
逻辑错误
异常的类型体系结构
Java中一切皆对象。所以,Java中的异常也是用“对象”表示的。
对象是类创建的对象,所以我们要先认识异常的类型。
API:Application Program Interface 应用程序编程接口。这里就是指编写java程序所用到核心类库
API文档:应用程序编程接口的说明问题。
API文档可以从官方下载,下载下来都是html网页文件,而且是一大堆。很多人,为了文档的传输和使用,把这些html文件用某些工具合成了xx.chm的文件。
Java中所有的异常和错误的超类是 java.lang.Throwable。
只有对象是此类(或此类子类之一)的实例时,才能通过java虚拟机或者java Throw(抛出)语句抛出。
类似的,只有此类或其子类之一的才可以时Cath(捕获)子句中的参数类型。
两个子类的实例,Error 和 Exception。通常用于只是发生了异常情况。
1,Error时Throwable的子类,用于指示合理的应用程序不试图图捕获的严重错误 问题。
VirtualMachineError(虚拟机错误)当java虚拟机奔溃或用尽了他继续操作所需的资源的时候,抛出该错误。
他的子类 StackOverflowErorr(栈内存溢出错误,在递归的时候见过
OutOfMemoryError(堆溢出错误)
Exception类和其子类时throwable的一种形式,他指出了合理的应用程序想要捕获的条件。
虽然catch 可以捕获所有的Execption,但实际开发中,不要把所有的Execption都用catch、解决。
关于Exception又分为两大类:
1.编译时异常,或者受检异常:这类异常,编译时会给出“预警”,提醒,无论这个异常时候会真的发生,只要没 可能发生,他就会提醒你,提前做好准备工作。
2.运行时异常,或者非受检时异常:这类异常,编译器不处理,或者说根本不看,无论你是否真的发生,编译时都不会给你任何提示。运行时异常时RuntimeExecption及其子类,凡是Runtime Execption系列以外的都是编译时异常,包括Execption。
回忆:
ArrayIndexOutOfBoundsExecption(数组下标越界异常)
NullPointerExecption (空指针异常)
ClassCastExecption(向下转型时异常)
InputMismatchExecption(输入不匹配异常)
ArithmeticExecption(运行时异常)
异常的处理
try - catch
try{
可能发生异常的代码1
可能发生异常的代码2
可能发生异常的代码3
}catch(异常的类型 参数名){
提示发生xx异常,或输出异常的相关信息
处理异常的代码
}catch(异常的类型 参数名){
提示发生xx异常,或输出异常的相关信息
处理异常的代码
}catch(异常的类型 参数名){
提示发生xx异常,或输出异常的相关信息
处理异常的代码
}
-
如果有多个catch分支,从上往下依次匹配,如果上面的匹配了,就执行上面的catch分支,下面的就不看了。类似于if-else if 多分支条件判断。如果多个catch分支的异常类型有父子类关系,那么遵循子上父下的顺序。如果多个catch分支的异常类型没有父子类关系,那么顺序无所谓,通常习惯上是把可能性大的放上的,可能性小的放小的。
-
如果try{}中没有异常发生,那么所有的catch都不会执行。
-
如果try{}中发生了异常,如上,如果try中语句2发生了异常,那么语句3是不会执行的。从发生异常的位置就中断了,去匹配下面的catch分支执行了
try-catch-finally 或 try-finally
try{
可能发生异常的代码1
可能发生异常的代码2
可能发生异常的代码3
}catch(异常的类型 参数名){
提示发生xx异常,或输出异常的相关信息
处理异常的代码
}catch(异常的类型 参数名){
提示发生xx异常,或输出异常的相关信息
处理异常的代码
}catch(异常的类型 参数名){
提示发生xx异常,或输出异常的相关信息
处理异常的代码
}finally{
这里面的代码是“一定”要执行的代码。
“一定”:
无论try中是否发生异常,finally都要执行
无论有没有catch,以及catch是否能够捕获try中发生的异常,finally都要执行
就算try或catch中有return语句,finally也要执行
但有一种情况除外,就是try或catch中执行了 System.exit(0); 因为这句话会让JVM退出。
}
throws(关键字)
当前方法的{方法体}中==“可能”==发生xx异常,并且在当前{方法体}中没有用try-catch处理这个异常,而是想要把这个异常交给“调用者/使用者”处理,表示谁调用谁处理。这种情况下,需要在方法签名后面加throws。
throws后面加什么呢?
hrows后面跟的是1个或多个的异常的类名。
方法重写时throws的要求
关于throws的使用,还有一点需要补充:在方法重写的时候有要求。
为什么 权限修饰符:>= ?
因为编译时按照父类的权限修饰符检查的,可以访问,当运行时执行子类重写的方法时,也必须保证权限修饰符是可见的。
为什么返回值类型 :<=?
因为编译时 按照父类的方法 的返回值类型 声明变量接收,实际运行时执行子类重写的方法,返回值的结果要<=该变量的类型。
为什么 异常类型必须<=?
因为编译时 按照父类的方法 声明的throws异常类型处理的,实际运行时执行子类重写的方法发生的异常类型必须<=catch里面填写的异常类型
throw(关键字)
结构:
throw 异常对象;
throw用于手动抛出一个异常对象。
思考?throws和throw的区别
-
throws单词后面加的是异常的类型,1个或多个异常的类型名,throw单词后面加的是一个异常对象。
-
throws是写在()后面{}的前面,throw语句是写在{}的里面。
throw语句的下面不能写其他语句,因为它和return一样,会让当前方法结束执行。
-
return是正常结束。
-
throw是带着异常对象回去,异常结束。
4、自定义异常类型
自定义异常类型,意思是我们自己声明一个class,让这个class作为异常的一种类型。
要求:必须继承Throwable或它的子类。然后用throw语句抛出。
为什么要自定义异常类型?目的:见名知意
例如:
需求银行卡的取款金额必须是正数,如果是负数,抛出 金额不能为负数的异常。
要求银行卡的取款金额必须小于余额,如果超过余额,抛出 余额不足的异常。