Java异常处理的五个关键字: try、catch、finally、throw、throws
在编写程序时,我们必须要考虑程序出现问题的情况。比如,在定义方法时,方法需要接受参数。那么,当调用方法使用接受到的参数时,首先需要先对参数数据进行合法的判断,数据若不台法,就应该告诉调用者,传递合法的数据进来。这时需要使用抛出异常的方式来告诉调用者。
在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。
抛出异常后:
① 创建一个异常对象。封装一些提示信息(信息可以自2编写)。
② 需要将这个异常对象告知给调用者。怎么告知呢?怎么将这个异常对象传递到调用者处呢?通过关键字throw就可以完成。throw 异常对象。
throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
使用格式:
throw new xxxException(“异常产生的原因”);
注意:
① throw关键字必须写在方法的内部。
② throw关键字后边new的对象必须是Exception或者Exception的子类对象
③ throw关键字抛出指定的异常对象,我们就必须处理这个异常对象。
Throw关键字后边创建的是RuntimeException或者是RuntimeException的子 类对象。我们可以不处理默认交给JVM处理(打印异常对象,中断程序)。
throw关键字后边创建的是编译异常(写代码的时候报错),我们就必须处理这个异 常,要么throws,要么try…catch。
以后(工作中)我们首先必须对方法传递过来的参数进行合法性校验,如果参数不合法,那么我们就必须使用抛出异常的方式,告知方法的调用者,传递的参数有问题。
0bjects类由一些静态的实用方法组成 。这些方法是null-save (空指针安全的)或null-tolerant (容忍空指针的),那么在它的源码中,对对象为null的值进行了抛出异常操作。
● public static T requireNonNull(T obj) : 直看指定引用对象不是null。(可以直接用这个方法判断是否为空)
查看源码发现这里对为null的进行了抛出异常操作:
声明异常: 将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理,那么必须通过throws进行声明,让调用者去处理。
关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。
声明异常格式(方法声明时使用):
注意事项:
① throws关键字必须写在方法声明处。
② throws关键字后边声明的异常必须是Exception或者是Exception的子类。
③ 方法内部如果抛出了多个异常对象,那么throws后边必须也声明多个异常如果 抛出的多个异常对象有子父类关系,那么直接声明父类异常即可。
④ 调用了一个声明抛出异常的方法,我们就必须的处理声明的异常要么继续使用 throws声明抛出,交给方法的调用者处理,最终交给JVM要么try…catch自己 处理异常。
如果异常出现的话,会立刻终止程序,所以我们得处理异常:
① 该方法不处理而是声明抛出,由该方法的调用者来处理(throws)。
② 在方法中使用try…catch的语句块来处理异常。
try-catch的方式就是捕获异常。
● 捕获异常: Java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定方 式的处理。
捕获异常语法如下:
try{
//可能产生异常的代码
}catch(/*定义一个异常的变量,用来接收try中抛出的异常对象*/){
//异常的处理逻辑,异常对象之后,怎么处理异常对象
//一般在工作中。会把异常的信息记录到一个日志中
}
catch(/*异常类名变量名*/){
}
注意:
① try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象
② 如果try中产生了异常,那么就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,维续执行try…catch之后的代码
③ 如果try中没有产生异常,那么就不会执行catch中异常的处理逻辑,执行完try中的代码,继续执行try…catch之后的代码
Throwable类中定义了一些查看方法:
● public String getMessage(): 获取异常的描述信息,原因(提示给用户的时候就提示错误原因),返回此throwable 的简短描述。
● public String toString() : 获取异常的类型和异常描述信息(不用),返回此throwable 的详细消息字串。
● public void printstackTrace(): 打印异常的跟踪栈信息并输出到控制台,默认此方法,打印的异常信息是最全面的。
包含了异常的类型异常的原因还包括异常出现的位置在开发和调试阶段都得使用printStackTrace。
在开发中呢也可以在catch将编译期异常转换成运行期异常处理。
finally:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。
什么时候的代码必须最终执行?
当我们在try语句块中打开了一些物理资源(磁盘文件/网络连接/数据库连接等),我们都得在使用完之后,最终关闭打开的资源。
finally的语法:
try…catch…finally : 自身需要处理异常,最终还得关闭资源。
注意finally不能单独使用。
比如之后的I0流中,当打开了一个关联文件的资源,最后程序不管结果如何,都需要把这个资源关闭掉。
finally代码参考如下:
多个异常使用捕获处理方式:
① 多个异常分别处理。
② 多个异常一次捕获,多次处理。
③ 多个异常一次捕获一次处理。
一般是使用一次捕获多次处理方式,格式如下:
注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,那么子类异常要求在上面的catch处理。父类异常在下面的catch处理。
● 运行时异常被抛出可以不处理,即不捕获也不声明抛出,默认给虚拟机处理。
● 在try/catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收。
● 如果finally有return语句,永远返回finally中的结果,避免该情况。
● 如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集。
● 父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
父类异常是什么样,子类异常就是什么样。
一个try多个catch注意事项:
catch里边定义的异常变量,如果有子父类关系,那么子类的异常变量必须写在上边,否则就会报错。