异常
异常的概念
异常:是指程序在运行过程中,出现的非正常的情况,最终会导致JVM非正常停止
注意:
异常并不是语法错误,语法错误编译不通过,不会产生字节码文件,根本不能运行
异常分类
异常处理
方法一:
alt+enter
抛出这个异常throws
将异常抛出给虚拟机处理
虚拟机处理异常的方式就是中断处理,将程序中断,将异常信息打印在控制台
方法二:
alt+enter
选择try catch
异常
将异常处理之后程序可以继续执行
try{
//可能出现异常的代码
}catch(Exception e){
//异常的处理逻辑
}
异常的产生过程?
比如说数组越界异常,当访问数组中不存在的索引时,JVM就会检测出程序会出现异常,此时JVM会做两件事:
- JVM会根据异常产生的原因创建一个异常对象,包含了异常产生的内容,原因,位置
- 在出现异常所在的方法中如果没有异常的处理逻辑(try…catch),那么JVM就会把异常对象抛出给方法的调用者(调用这个方法的方法)来处理这个异常,若是该方法的调用者也没有异常的处理逻辑,那么继续将异常抛出给他的调用者
…
最终会将抛给JVM
JVM会执行两步:- 把异常对象(内容,原因,位置)以红色的字体打印在控制台
- JVM会终止当前正在执行的java程序—》中断处理
异常的处理
抛出异常throw
throw关键字:
- 作用:使用throw关键字来抛出指定的异常。
- 如何使用?
throw new xxException("异常产生的原因");
比如说传递的数组为空
if(arr == null){
//对数组判空
throw new NullPointerException("传递的数组的值是传递ull");
}
- 使用时应该注意:
1. throw必须卸载方法的内部
2. 被throw抛出指定的异常对象后我们应该处理该异常
(如果该异常对象是RuntimeException或是RuntimeException的子类我们可以不处理,默认交给JVM处理;如果后面跟的是编译异常,我们就必须要处理)
注意:在写方法时我们首先要对方法传递过来的参数进行合法性校验,如果参数不合法,那么必须要使用抛出异常的方式告知方法的调用者传递的参数有问题
异常的第一种处理方式–声明异常throws
throws关键字:
- 作用:用throws声明异常,将问题标识出来,报告给调用者。
当方法内部抛出异常对象的时候,我们必须要处理这个异常对象
可以使用throws关键字处理异常对象,会把异常对象声明抛出给方法的调用者处理(自己不处理,给别人处理),最终交给JVM处理–》中断处理
关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常) - 如何使用:
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2....{}
public static void main(String[] args) throws InterruptedException {
Thread.sleep(9999999L);
}
- 注意:
1. throws关键字必须要写在方法声明处
2. 调用了一个声明抛出异常的方法,我们就必须的处理声明的异常
(要么继续使用throws声明抛出,交给方法的调用者处理,最终交给JVM;要么try…catch自己处理异常) - 缺陷:
异常后面的代码不执行(因为发现异常之后最终交给JVM处理,JVM中断处理,后续代码不执行)
异常的第二种处理方式 --捕获异常 try catch
try-catch捕获异常:
- 如何使用:
try{
//可能会产生异常的代码
}catch(异常类名 变量名){
//处理异常对象的方法
}
...
- 注意:
- try中可能会抛出多个异常对象,那么就可以使用多个catch来处理这些异常对象
- 如果try中的代码产生了异常,那么就会执行catch中的异常处理代码,执行完后继续执行try-catch之后的代码;
如果try中的代码没有产生异常,那么就不会执行catch中的异常处理代码,而是继续执行try-catch之后的代码;
finally代码块
无论异常是否发生都会执行的代码块
使用注意:
- finally 不能单独使用,必须和try一起使用
- finally一般用于资源释放(资源回收),无论程序是否出现异常,最后都要资源释放
- 建议return不要放在finally块中 因为可能会抑制catch或try当中的return
异常注意事项
- 运行时异常被抛出可以不处理,既不捕获也不声明抛出
- 如果父类抛出了多个异常,父类覆盖子类方法时,只能抛出相同的异常或是他的子类
- 父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
- 在try catch后可追加finally代码块,其中的代码一定会被执行,通常用于资源回收
自定义异常类
- 如何定义:
自定义异常时需要自己定义一个异常类实现 该类继承于Exception或RuntimeException
(继承自 Exception 的异常默认是编译异常(也叫受查异常),继承自 RuntimeException 的异常默认是运行时异常) - 如何使用:
public class xException extends Exception/RuntimeException{
添加一个空参数的构造方法
添加一个带异常信息的构造方法
}
格式类比空指针异常的源码