第10章异常处理

第9章 异常处理

java异常机制主要是依赖于try catch finally throw throws 五个关键字,其中throws关键字主要是在方法签名中使用,用于声明该方法可能抛出异常,throw用于抛出一个实际的异常,throw可以单独作为语句使用,抛出一个具体的异常对象

10.1异常概述

增加异常处理机制后的程序又更好的容错性,使程序更健壮

 

10.2异常处理机制

10.2.1 使用try catch捕捉异常

如果执行try块里的代码出现异常,该异常对象会被提交个java运行时环境,这个过程被称为抛出异常 如果找不到捕获异常的catch 则运行时环境将终止(JVM + java APIJava应用程序设计接口))

不管程序代码是否处于try中 只要执行该代码出现异常时,系统都会自动生成一个异常对象,如果程序没有定义这段代码的catch,那么程序就在此退出

10.2.2 异常类的继承体系

try catch 块后的{}不可以省略

RuntimeException 子类(空指针异常 造型异常)

10.2.3 java7 提供多异常捕获

java7 之前 每个catch块只能捕获一个异常,但7开始就可以捕获多个异常

使用一个catch块捕获多个异常时需要注意

1.捕获多种异常时,多种异常之间用 | 隔开

2.捕获多种类型的异常时,异常变量有隐式的final修饰,因此程序不能对异常变量重新赋值

 

捕获一种异常时没有隐式的final修饰

10.2.5 使用finally回收资源

异常处理语法结构中只有try快是必须的,但catch finally块必修出现一种

 

当 程序中同时出现 catch finally时  catch中如果有 return语句 也必须先执行完finally时才会强制方法结束 除非在异常处理块中调用了System.exit(1)退出虚拟机

 

一般不要在finally中使用 return throw 语句,否则将导致 try catch中的return或者throw得不到执行

 

10.2.7java的自动关闭资源的try语句

java 7 允许在try关键字后紧跟一对括号,括号里可以声明、出初始化一个或者多个资源(数据库连接、I/O)try语句结束后这些资源会自动关闭

为了保证这些资源能被正常关闭,这些资源的实现类必须实现AutoCloseable 或者Closeable接口,实现这两个接口就必须是实现close()方法

 

10.3 Checked异常和 Runtime 异常体系

只有java提供了Checked异常,java认为检查性异常都是可以修复的异常,所以java必须显示处理Checked异常

Check异常处理有两种方法

1.用try catch块来捕捉,然后在catch块中修复该异常

2.当前方法不知道如何处理这种异常,应该在定义该方法时声明抛出异常

 

10.3.1使用throws声明抛出异常

使用throws声明抛出异常的思路是,当前方法不知道如何处理这种类型的异常,该异常应该上抛给上一级调用者来处理;如果main方法也不知道如何处理,也可以使用throws声明抛出异常交给jvm处理 (如果是多线程就由Thread.run()抛出

jvm对异常的处理是 打印异常的跟踪栈信息,并中止程序运行,这就是前面程序在遇到异常后的自动中止的原因

throws声明抛出异常只能在方法签名中使用,throws可以声明抛出多个异常类 异常类之间用 “,  隔开

throws抛出异常时有一个限定子类抛出的异常不能比父类的多 子类跑出来的异常的类型不能比父类的大

 

检查性异常至少有两个不方便之处

1. 对于程序中的检查性异常必须要显示捕捉处理或者显示抛出异常

2. 如果在方法中抛出异常,将会导致方法签名与异常耦合,如果该方法是重写的父类方法,则方法抛出的异常还有受到被重写的方法抛出异常的限制

 

10.4 使用throw抛出异常

当程序出现错误,系统会自动抛出异常,初次之外,java也允许程序自行抛出异常,自行抛出异常使用throw来完成 throw语句抛出的异常不是异常类,而是异常类的一个实例,而且每次都只能抛出一个异常实例

不管是系统自带的还是程序手动抛的异常,java运行时环境对异常处理没有任何差别

如果throw语句抛出的异常时检查性异常,则该异常要么处于try块里,要么放在一个带throws声明的方法中; 如果throw语句抛出的异常时运行时异常,则可以不用显示处理异常

10.4.2 自定义异常

自定义异常都要继承Exception类,如果希望自定义Runtime异常,则应该程序RuntimeException

定义异常时通常都需要两个构造器 一个无参 另一个是带字符串的构造器

10.4.3 catchthrow同时使用

对于异常处理一般分成两个部分

1.应用后台需要通过日志来记录异常发生的详情

2.应用还需要根据异常向运用这传递一些异常发生的详细信息

 

10.4.4 java 7 增强的throw语句

java 7 开始 java编译器会执行更细致的检查,java编译器会检查throw语句抛出的异常的实际类型

 

10.4.5 异常链

通常程序先捕捉原始异常,然后抛出一个新的业务异常,新的异常包含了对用户的提示信息

这种把捕捉的原始异常隐藏起来,仅向上提供必要的异常提示信息处理方式,可以保证底层异常不会扩散到表现层,可以避免向上暴露太多的实现细节,这种把捕获一个异常然后接着抛出另一个异常,并把原始异常信息保存下来的典型链式处理(责任链模式 或者异常链)

10.6异常处理规则

成功的异常处理应该实现如下4个目标

1.使程序代码混乱最小化

2.捕捉并保留诊断信息

3.通知合适的人员

4.采用合适的方式结束异常活动

 

10.6.1 不要过度使用异常

异常处理机制的初衷是将不可预期的异常处理代码和正常的业务逻辑处理代码分离,因此不能使用异常处理代码来代替业务逻辑处理

10.6.2 不要忽略捕捉到的异常

建议通常对异常处理的措施

1.处理异常 对异常进行合适的修复,然后绕过异常发生的地方继续执行,或者用别的数据代替计算,或者提示重新输入,检查异常应该尽量修复

2.重新抛出新的异常

3.在合适的层处理异常

 

你可能感兴趣的:(java,异常)