1. 以数组访问越界为例:
a. JVM会根据异常产生的原因创建一个异常对象,该对象包含了异常产生的(内容,原因,位置)信息
b. 如果该层未对异常进行处理,则会将异常向上抛出给方法的调用者
c. 如果最后main方法接收到了异常,但是也没有处理该异常,则会将异常抛给JVM
d. JVM接收到异常对象后,会以红色字体将异常对象打印在控制台并终止当前执行的java程序
异常的处理:throw/try{}catch{}/finally/throws
1.throw关键字
a. 使用格式:
thrownewxxxException("异常产生原因");
b. 注意事项:
1.throw关键字必须写在方法的内部
2.throw关键字抛出的对象必须是Exception或Exception的子类对象
3.throw关键字后如果创建的时RuntimeException或者其子类对象,则允许交给JVM处理
4.throw关键字后如果创建的是编译时期异常,就必须处理该异常,要么throws,要么try/catch
c. 例如:参数合法性校验
publicstaticintgetElement(int[] arr,int index){if(arr == null){thrownewNullPointerException("传递的数组值为null");}if(index<0|| index>arr.length){thrownewArrayIndexOutOfBoundsException("索引越界");}return arr[index];}2.throws关键字
a. 作用:
当方法内部抛出异常时,我们可以暂时不处理,使用throws关键字抛给方法的调用者处理
b. 使用格式:
修饰符 返回值类型 方法名(参数列表)throws AAAException,BBBException...{thrownewAAAException("AAA异常原因");...thrownewBBBException("BBB异常原因");}
c. 注意事项:
1.throws关键字必须在方法声明处
2.throws关键字后声明的异常必须时Exception或者其子类
3. 如果方法内部抛出了多个异常,则throws后也必须声明多个异常,如果异常存在父子类关系,则声明父类异常即可
4. 调用了一个声明抛出异常的方法,要么继续throws声明抛出,要么try/catch处理该异常
3.try/catch关键字
a. 格式:
try{//可能抛出异常代码}catch(异常名 变量名){//异常处理逻辑}...catch(异常名 变量名){//异常处理逻辑}
b. 注意事项:
1.try中可能抛出多种异常,可以使用多个catch捕获不同异常分别处理
2. 如果try中抛出异常,则执行catch中异常处理代码,然后继续执行try/catch后代码
2. 如果try中没有抛出异常,则不执行catch代码,直接向后执行
c. Throwable类中定义了3个处理异常的方法:
String getMessage();//返回throwable的简短描述
String toString();//返回throwable的详细消息字符串voidprintStackTrace();//默认此方法打印,JVM打印异常对象,显示信息最全面4.finally关键字
a. 使用格式:
try{}catch(){}...catch(){}finally{//无论是否出现异常都会执行}
b. 注意事项
1.finally不能单独使用,必须与try结合使用
2.finally一般用于资源释放(资源回收,不论是否出现异常,都要回收资源)3. 如果finally中有return语句,则永远返回的是finally中的值,所以不应该在finally中return
父子类的异常处理
1. 如果父类抛出了异常,则子类
a. 抛出父类相同的异常
b. 抛出父类异常的子类
c. 不抛出异常