目录
异常的处理之throw
2020年7月28日
23:28
throw关键字:
作用:
可以使用throw关键字在指定的方法中抛出指定的异常
使用格式:
throw new xxxException("异常产生的原因");
注意:
1、throw关键字必须写在方法的内部
2、throw关键字后边new的对象必须是Exception或Exception的子类对象
3、throw关键字抛出指定的异常对象,我们就必须处理这个异常对象
throw关键字后边创建的的是RuntimeException或者是RuntimeException的子类对象,我们可以不处理,默认交给JVM处理
若创建的是编译异常(写代码时),我们就要throws或是try-catch
使用场合:
以后(工作中)我们首先必须对方法传递过来的参数进行合法性校验
如果参数不合法,那么我们就必须使用抛出异常的方式,告知方法的调用者,传递的参数有问题
演示:
public static void main(String[] args) {
int []arr={1,2,3};
int e=getElement(arr,-1);
System.out.println(e);
}
public static int getElement(int []arr,int index){
/*
对传递来的参数数组,进行合法性校验
如果参数不合法,那么我们就必须,使用抛出异常的方式,告知方法的调用者,传递的参数有问题
*/
if (arr==null){
//这里空指针异常是RuntimeException运行期异常,不用处理,交给jvm
throw new NullPointerException("传递的数组为空");
}
else if (index>arr.length-1||index<0)
throw new ArrayIndexOutOfBoundsException("越界了兄弟!");
return arr[index];
}
传参:
结果:
传参:
结果:
Objects非空判断
Objects类中对对象为null的值进行了抛出异常
源码:
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
演示:判断参数是否为null
public static void main(String[] args) {
method(null);
}
public static void method(Object o){
/* 使用Objects.requireNonNull(o);后被替代的写法if (o==null)
throw new NullPointerException("传递的对象值是null");*/
/*Objects.requireNonNull(o);*/
//重载的方法
Objects.requireNonNull(o,"传递的对象值是null");
}
throws
异常处理的第一种处理方式
作用:当方法内部抛出异常对象时,那么我们就必须处理这个异常对象
可以使用throws关键字处理异常,会把异常对象声明抛出给方法的调用者处理(自己不处理,给别人处理),最终交给JVM处理-->中断处理
格式:在方法声明时使用
修饰符 返回值 方法名(参数列表) throws AAAException,BBBException…{
throw new AAAException("产生原因");
throw new BBBException("产生原因");
…
}
注意事项:
1、throws关键字必须写在方法声明处
2、throws后边声明的异常必须是Exception或Exception的子类
3、方法内部如果抛出了多个异常对象,那么throws后边也必须声明多个异常
如果抛出的多个异常对象有子父类关系,那么自己声明父类异常即可
4、调用了一个声明抛出异常的方法,我们就必须处理声明的异常
要么继续使用throws声明抛出,交给方法的调用者处理,最终交给jvm
要么try-catch自己处理异常
示例: 定义一个方法,对传递的文件路径进行合法性判断
public static void main(String[] args) throws FileNotFoundException {
//调用了会抛出异常的方法,继续声明throws交给jvm处理
readFile("c:\\a.xt");
}
public static void readFile(String fileName) throws FileNotFoundException {
if (!fileName.equals("c:\\a.txt"))
//这里的FileNotFoundException会出现一个编译时异常要处理
throw new FileNotFoundException("传递的文件路径不是c:\\a.txt");
当抛出了多个异常,添加一个:
if (!fileName.endsWith(".txt"))
throw new IOException();
IOException是FileNotFoundException异常的父类那么抛出的异常可以直接抛出IOException
try…catch
异常处理的第二种方式,自己处理
格式:
try{
可能产生异常的代码
}catch(定义一个异常变量,用来接收try中抛出的异常对象){
异常的处理逻辑,产生异常对象之后,怎么处理对象
一般在工作中,会把异常的信息记录到一个日志中
}
…
catch{
…
catch(异常类名 变量名)
}
注意:
1、try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象
2、如果try中产生了异常就会执行catch中的异常处理逻辑,执行完毕catch中的处理逻辑,继续执行try…catch之后的代码
如果try中没有产生异常,那么就不会执行catch中异常处理逻辑,执行完try中的代码,继续执行try-catch之后的代码
演示:承接上节代码
try {
readFile("c:\\a.xt");
} catch (IOException e) {
e.printStackTrace();
System.out.println("文件的目录有问题");
}
System.out.println("后续代码");
Throwable类中3个处理异常的方法
String getMessage() 返回此throwable的简短描述
String toString() 返回此throwable的详细消息字符串
void printStackTrace()Jvm打印异常对象,默认调用此方法,打印的异常信息最全面
演示:承接上面的代码
catch (IOException e) {
System.out.println(e.getMessage());
System.out.println("=========");
System.out.println(e.toString());
System.out.println("=========");
e.printStackTrace();
错误有时会延迟打印到控制台
finally
解决的问题:有一些特定的代码,无论异常是否发生都需要执行,因为异常会引发程序跳转,导致有些语句执行不到。
finally语法
在catch之后
catch{
/代码/
}
…
finally {
System.out.println("资源释放");
}
异常的注意事项
多个异常使用捕获
1、多个异常分别处理
2、多个异常一次捕获,多次处理
注意:catch里边定义的异常变量,如果有子父类关系,那么子类的异常变量必须写在上边,否则就会报错
原因:try中抛出的异常会依次赋值给catch,子类在前,赋值到父类的时候是多态,而父类在前则不行
3、多个异常一次捕获一次处理
直接catch所有异常的父类异常(例如Exception)
运行时异常的抛出可以不处理。即不捕获也不声明抛出
默认给虚拟机处理
如果finally有return语句,永远返回finally中的结果,避免这种情况
也就是说在被调用的方法中有返回值,避免在该方法的finally中使用return不然只会return finally中的内容,因为finally是最终执行的
总结:父类异常是什么样,子类异常就是什么样
子父类异常问题
如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常
父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生异常,只能捕获处理,不能抛出
在try-catch后可以追加finally代码块,其中的代码一定会被执行,通常用于资源回收