异常的体系结构
查看API,发现Exception类及其子类都是Throwable的一种形式
Exception 代表 的是 java程序中可能会产生的异常,并要求对产生的异常进行合理的异常处理。
整个异常的体系结构:
Throwable
Exception:需要处理 Error:程序员一般不用处理
(能治愈的疾病) (不可治愈的疾病)
检查异常 运行时异常
编译器异常 运行时期出现的异常
Throwable
Throwable 类中常用方法
1> String getMessage() 返回异常信息
/ by zero
2> void printStackTrace() 使用红色字体打印错误信息(异常名称,错误信息,位置)
java.lang.ArithmeticException: / by zero
at com.override.Demo.main(Demo.java:7)
3> String toString()
使用简短的字符串描述错误
java.lang.ArithmeticException: / by zero
异常和错误的区别
异常: 指 程序在编译、运行期间发生了某种异常(xxxxxxxException),我们可以对异常进行具体的 处理,
若不处理程序就会结束运行。
错误: 指程序在运行期间发生了某种错误(XXXXXError),Error错误通常没有具体的处理方式
程序将会结束运行,Error错误发生往往是系统级别的问题例如JVM所在系统发生的
并且反馈给JVM,我们无法针对处理,只能修改代码
异常的分类
- 回忆: A.java -----编译器javac.exe编译------> A.class -------解释器java.exe运行-- 机器码
- 编译时检查异常: 在编译阶段就会出现的异常
- 运行时异常(RuntimeException): RuntimeException及其它的子类,可以通过编译,但是在运行 的时候出现的异常
异常的产生的过程
在编写程序时,我们必须要考虑程序出现问题的情况。
例如: 在定义方法时,方法需要接收参数,那么当调用方法时,
需要给方法的参数赋值, 首先需要对参数进行合法的判断,
若数据不合法,就应该告诉告诉调用者,你传递的参数是错误的
需要传递合法的参数,这时可以通过抛出异常的方式告诉他。
throw 关键字
抛出异常“对象”
- 作用: 可以使用 throw 关键字,在指定的方法中抛出指定的异常对象
- 格式: throw new XXXXXException(“填写异常产生的原因”);
- 注意: ① throw 关键字 必须写在方法的内部
② throw 关键字 后面 new 对象必须是 Exception 或者 Exception的子类
③ throw 关键字
情况1: 抛出的是 检查异常,则我们必须处理这个异常
hrow new Exception(“异常的原因”);
我们必须要手动处理这个异常,
处理异常有两种: 不负责任 throws往外抛
负责任 try…catch
情况2: 抛出的是 运行时异常(RuntimeException 或者 RuntimeException的子类)
我们可以不处理,默认交给JVM处理(打印错误信息,中断程序)
异常处理的方式
① try…catch…finally 捕获异常(自己处理)
捕获: java中对异常有针对性的语句进行捕获,可以对出现的异常进行指定的方式处理
格式:
try{// 可能产生异常的代码(没有异常的代码也可以定义在try中)
// try块中,一旦出现异常,则抛出异常的那句代码后面的代码都不执行啦
// 疑似病人(可能有病,或者没有病)
}catch(异常类名 变量名){
// 数据类型,必须是Exception或者Exception的子类
// 新冠病 ,匹配这个,才会执行这个代码,就会进隔离区
//异常的处理语句,抓取到 和 异常类名一样的的对象才执行
}catch(异常类名2 变量名){
// 普通流感 ,匹配这个,才会执行这个代码
}finally{
//不论是否有异常,finally中内容都会执行(执行1遍)
//不论是有病还是没病,都会从新检测指标
}
System.out.println("1**"); //以下的代码就可以正常的执行啦
注意:
1. try 存放是可能会出现异常的代码,异常有0个或者n个
2. catch 用来进行某种异常的抓取,实现对抓到的异常对象进行处理
一个try可以匹配多个catch,catch是有顺序要求的
1> 若多个catch的异常类之间没有继承关系,则顺序随便
2> 若多个catch的异常类之间有继承关系,则 子类异常必须在父类异常的上面
3. finally: 不论是否有异常都会执行
②throws 抛出异常(交给别人处理)
作用: 当方法内部抛出异常对象的时候,我们必须处理这个异常对象 可以使用throws 抛出异常
抛给谁? 抛给方法的调用者处理(自己不处理,给别人处理)
如果到了main方法,还继续往外抛出,则 最终交给JVM(1.打印错误信息 2.中断程序)
格式:
public 返回值类型 方法名(参数列表) throws AaaaaException,BbbbbException{
// throw new AaaaaException("产生原因");
// throw new BbbbbException("产生原因");
}
注意: throws 关键字 必须写在方法的声明处
throws 关键字 后面必须是 Exception 或者 Exception 子类
方法内部如果抛出了多个异常对象,那么 throws 后面也必须声明多个异常对象
如果抛出多个异常对象存在父子关系,那么直接抛出父异常就可以
异常在重写中细节
1. 子类 重写 父类的方法时,
如果 父类的方法声明了异常
子类重写的方法
只能声明 父类异常或者该异常的子类
或者选择不声明任何异常。
package com.try_catch_finally;
//检查异常
class AException extends Exception{
public AException() {super();}
public AException(String msg) {super(msg);}
}
class BException extends AException{
public BException() {super();}
public BException(String msg) {super(msg);}
}
class CException extends Exception{
public CException() {super();}
public CException(String msg) {super(msg);}
}
class F{ //alt+/
public void m1() throws AException{
System.out.println("F---m1");
}
}
class S extends F{
//抛开运行时异常
//重写
// 选择1: 不抛
// 选择2: 和父类抛出一样的异常 AException
// 选择3: 父类异常的子类异常 BException
//就是不能抛出父类异常的父异常,和其他异常
public void m1() throws AException{
System.out.println("S---m1");
}
}
public class Demo4 {
}
2. 父类的方法没有抛出异常,子类重写父类的方法时也不要抛出异常
若子类产生了检查异常,则自己在方法内部try..catch处理,不要抛出
若子类产生了运行时异常,则不用处理,因为JVM会处理
自定义异常
- 创建一个类继承 Exception或者Exception的子类
- 在类中定义2个构造方法 一个无参 一个有String参数的
- 分别在构造方法中调用对应的父类的构造方法
如何使用自定义异常
若程序没有满足你的需求时,
可以抛出一个自定义的异常对象 throw new XXXXException(“原因”);