导致程序运行不正常的突发情况称为异常
异常的架构
异常都属于Throwable类
Throwable类有两个子类:Error和Exception
Error类属于不可控的系统级异常,这不是程序本身的问题。这种异常不太容易发生,即使发生了我们所能做的处理也
很有限这类错误产生的原因如:内存不足,线程死锁........
Exception类是可控式异常,在程序中可以对其进行控制
Exception类有子类RuntimeException,所有其它不是RuntimeException的异常类统称为CheckedException
RuntimeException是设计的代码错误导致的,属于主观异常,运行时报错,发现问题修改即可,
无捕捉处理的意义.
CheckedException是外在因素导致的错误,属于客观异常,编译时报错,当然我们主要处理的异常即是此类
目的就是在程序编译时,运行前处理掉这些异常。提前预先到可能出现的异常,预防在客
户端使用时出现问题。
捕捉处理异常
捕捉异常 try...catch
格式如下:
try {
<可能产生异常的程序代码> }
catch {
<处理这个异常的程序代码> }
什么方法会产生什么样的异常?到哪里去找?方法一是到API中去找......
更多情况是程序编译时java直接告诉你哪一段代码会产生什么样的异常
并且要求你一定要去处理它...
所以问题的重点在于捕捉到这个异常后,我们去做什么处理。
异常处理
一般两个步骤:1.显示异常类的名称和一些相关的信息(即使什么也不做,程序也会跳过异常继续执行下去)
2.在安全的状况下恢复程序的运行(即让try中的代码能够得到正确运行)
显示异常信息的方法都继承自Throwable类,以下列出常见方法:
toString()
显示异常类的名称和产生异常的原因(比如直接把异常对象丢给打印语句则会自动调用次方法
:System.out.println(e); )
getLoucalizedMessage() ,getMessage()
显示异常产生的原因,两方法效果一样,用系统平台语言显示
printStackTrace()
显示产生这个异常的相关类名称以及是第几行程序代码产生这个异常
此方法有重载版本,带参数后可以改变显示的位置,比如文件
finally
跟在catch后,表示总要被执行的代码,无论是否发生异常,如果发生异常,那么finally语句块在catch语句
块执行后跟着执行。例外:
A. 在chatch中使用System.exit()方法中止程序
B. computer死机...停电...天灾人祸..........
异常执行的顺序:由于所有异常都继承自Throwable类,所以出现个问题,catch语句块可以有很多个,但是必须遵守
具体—>泛化 这样的捕捉顺序,不然更具体的异常类在后面什么也捕捉不到。
throws关键字:抛出异常,跟在方法参数列表后面,表示抛出异常给方法的调用者而不去处理它,一个方法可以同时
抛出多个异常,并且这种抛出异常不做处理的方式可以连续的一直往上抛,甚至可以抛出main方法
毕竟,设计异常的目的就是为了处理它,这样抛出不做处理没有任何意义,仅仅是能够让程序跳过
异常继续执行而已。
自己设计异常
throw关键字 "少个s" 可在方法内部任何位置抛出一个异常对象,常用来抛出Runtime Exception类异常
因为此异常不能用try...catch语句去捕捉,
并且抛出此类异常后,会显示详细的异常信息(和使用Throwable类的printStackTrace()方法显示的
一样)
并且抛出此类异常后,程序会中止,不会继续运行下去
这种利用throw关键字抛出Runtime Exception类异常的方式,我未见书上给出具体的应用情况
定义自己的Exception类
在自己定义的Exception类的构造方法中直接调用父类的构造方法,把参数参数忘上传就好了,真的很简单
除了构造方法外,另外加上什么样的方法都可以,和一个普通的类没有什么区别,该遵守的得遵守而已。
异常与方法的改写:
改写成功与否的判断的标准是,改写的方法丢出的异常必须能够自动转型为父类方法所丢出的类型
显然,如果不能自动往上转型肯定会出现错误
这点和改写方法时返回类型的要求一样(协变返回类型)
只能比父类做的更具体,不能比父类做的更泛化
由此,可见Java的异常处理机制是很巧妙很灵活的。把导致程序运行不正常的异常划分成组织结构良好的类,把异常 信息都包装在这些异常类中并返回给程序员,而且提供try...catch语句去处理异常,throws关键字抛出不处理异常。
这样要么中止程序,要么返回代码中去修改Runtime Exception异常,要么去处理Checked Exception类异常。
具体的处理可以是提供检查机制,当满足某一条件时执行"异常语句",或者是直接抛给导致出现问题的外因。
总之,java的异常处理机制的目标降低异常故障的损失,当然BUG到处都是,我们能做的只能是尽量在故障发生
之前做好万全的准备,预防这些Checked Exception 。
设计的巧妙之处就是把BUG分门别类,不可控的系统级Error“排除不管”,Runtime Exception类的异常出现后返回
去修改代码,Checked Exception类的异常提前预防,尽力总结成具体的异常类装入类库,在编译时解决掉。
统一采用try...catch语句来避免处理错误的逻辑和处理业务的逻辑混杂在一起,提高程序的可阅读性。
通过throws语句将可能出现异常的代码抛出去,集结在一处处理,避开代码空间的局限性。
而且避免了采用诸如传统的if...else等等检查机制导致的执行效率代价。