异常处理
1. 异常的重要性
没有没有异常的程序,80%的精力处理20%可能报错的代码
2. 异常和错误的分类
l 异常:(Exception)
n 编译时异常(checked exception 检查异常):编译器在编译代码中发现的
n 运行时异常(Runtime Exception 未检查异常):JVM在运行时发现的
解决方案:try—catch—finally捕获处理, throws往上抛。
l 错误:(Error)
n 无法用代码挽回,往往是硬件问题或运行环境问题。
3. 异常的继承结构
4. 如何处理异常
1. 异常抛出机制
在java语言中,异常是被一个方法抛出的对象。当一个方法抛出异常时,该方法从调用栈中被弹出,同时产生的异常对象抛给了栈中的前一个方法
2. 处理方式
1. 捕获这个异常,不让它沿着调用栈继续向下抛出
2. 捕获这个异常,并继续向下抛出
3. 不捕获这个异常,从而导致方法从调用栈中被弹出,异常对象继续抛给调用栈下面的方法
Thy—catch—finally
n try{正常逻辑的代码,但有可能发生异常}catch(异常类名 变量名){处理}finally{无论如何都要执行的代码}
n 一旦某一行发生异常,将产生异常对象,程序转向catch块,而try块剩下的代码不会被执行,
但程序会正常结束
n 一旦发生异常后 catch后面的异常变量能够匹配上,则表明我们对异常进行了捕获
n Catch块按顺序执行,当try块后面接多个catch块,如果catch块的异常变量没有继承关系,不影响顺序,如果有继承关系,那么父类将写在子类后面
.printStackTrace方法可以打印堆栈信息,开发测试阶段打印出未知异常的信息,便于进行代码的调整,而运行阶段往往把这句代码会注释起来。与虚拟机异常分别方法,没有第一句线程打印。
n 如果有一块代码不管是否发生异常抛出都要执行的代码,我们使用关键字finally,就算是return,break,continue也不能跳出finally语句,往往用来资源清理,连接的关闭,管道的关闭
n 语法细节:catch是有顺序的,try—catch—finally不能允许单独存在,catch、finally后面必须要有try。
Throw
抛出一个异常,throw new 异常数据类型;
Throws
在方法的声明后面实现前面,用throws关键字后面跟上会抛出异常类型的类名,表示本方法有可能会抛出某几种类型的异常。
细节:
n 一个方法的完整声明的形式包括了throws,甚至包含main方法也可以包含throws
n 方法重写的规范被更新,增加:子类被重写方法不能比父类抛出更多的异常,指异常范围而不是个数
n 只有在抛出编译时异常,调用者才会受到警告; 抛出运行时异常,调用者不会在编译期被警告。
| throw | throws |
位置 | 写在方法体当中,是一条执行语句 | 写在方法声明的最后,是一条声明语句 |
后面接的内容 | 后面接的是一个异常对象 | 后面接的是1个或多个异常类的类型名 |
效果 | 一旦执行到throw语句,就会有真正的发生1个异常对象被抛出的动作 | 表示本方法有可能抛出某种或某几种类型的异常,仅在编译期提示调用者 |
5. 怎么用处理异常
l 调用先人有throws的声明的方法,99%马上try—catch
l 运行时异常
n 多做if判断,不让异常有产生的机会
n 不是所有的异常都用try—catch,特别是空指针
n 1%的异常使用try—catch,重点考虑代码流程的控制
l throw 和 throws只有在大型分层项目中才有可能自己写
6. 自定义异常语法
l 必须是一个异常类(继承Exception)
l 自己添加的功能行为(构造方法和普通方法)
l 在一个方法中抛出异常
l 把抛出的异常信息装到自定义异常文件里